1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
9 # include <X11/extensions/shape.h>
15 #include "otk/timer.hh"
16 #include "blackbox.hh"
19 #define MwmHintsFunctions (1l << 0)
20 #define MwmHintsDecorations (1l << 1)
22 #define MwmFuncAll (1l << 0)
23 #define MwmFuncResize (1l << 1)
24 #define MwmFuncMove (1l << 2)
25 #define MwmFuncIconify (1l << 3)
26 #define MwmFuncMaximize (1l << 4)
27 #define MwmFuncClose (1l << 5)
29 #define MwmDecorAll (1l << 0)
30 #define MwmDecorBorder (1l << 1)
31 #define MwmDecorHandle (1l << 2)
32 #define MwmDecorTitle (1l << 3)
33 #define MwmDecorMenu (1l << 4) // not used
34 #define MwmDecorIconify (1l << 5)
35 #define MwmDecorMaximize (1l << 6)
39 // this structure only contains 3 elements... the Motif 2.0 structure contains
40 // 5... we only need the first 3... so that is all we will define
41 typedef struct MwmHints {
42 unsigned long flags, functions, decorations;
45 #define PropMwmHintsElements 3
51 BlackboxWindowList windowList;
54 BWindowGroup(Blackbox *b, Window _group);
57 inline Window groupWindow(void) const { return group; }
59 inline bool empty(void) const { return windowList.empty(); }
61 void addWindow(BlackboxWindow *w) { windowList.push_back(w); }
62 void removeWindow(BlackboxWindow *w) { windowList.remove(w); }
65 find a window on the specified screen. the focused window (if any) is
66 checked first, otherwise the first matching window found is returned.
67 transients are returned only if allow_transients is True.
69 BlackboxWindow *find(BScreen *screen, bool allow_transients = False) const;
73 class BlackboxWindow {
75 enum Function { Func_Resize = (1l << 0),
76 Func_Move = (1l << 1),
77 Func_Iconify = (1l << 2),
78 Func_Maximize = (1l << 3),
79 Func_Close = (1l << 4) };
80 typedef unsigned char FunctionFlags;
82 enum Decoration { Decor_Titlebar = (1l << 0),
83 Decor_Handle = (1l << 1),
84 Decor_Border = (1l << 2),
85 Decor_Iconify = (1l << 3),
86 Decor_Maximize = (1l << 4),
87 Decor_Close = (1l << 5) };
88 typedef unsigned char DecorationFlags;
90 enum WindowType { Type_Desktop,
99 enum Corner { TopLeft,
109 BlackboxAttributes blackbox_attrib;
111 Time lastButtonPressTime; // used for double clicks, when were we clicked
113 unsigned int window_number;
114 unsigned long current_state;
115 unsigned int mod_mask; // the mod mask used to grab buttons
117 enum FocusMode { F_NoInput = 0, F_Passive,
118 F_LocallyActive, F_GloballyActive };
119 FocusMode focus_mode;
122 bool moving, // is moving?
123 resizing, // is resizing?
124 shaded, // is shaded?
125 visible, // is visible?
126 iconic, // is iconified?
127 focused, // has focus?
128 stuck, // is omnipresent?
129 modal, // is modal? (must be dismissed to continue)
130 skip_taskbar, // skipped by taskbars?
131 skip_pager, // skipped by pagers?
132 fullscreen, // a fullscreen window?
133 send_focus_message, // should we send focus messages to our client?
134 shaped; // does the frame use the shape extension?
135 unsigned int maximized; // maximize is special, the number corresponds
136 // with a mouse button
137 // if 0, not maximized
138 // 1 = HorizVert, 2 = Vertical, 3 = Horizontal
142 Window window, // the client's window
144 BlackboxWindow *transient_for; // which window are we a transient for?
145 BlackboxWindowList transientList; // which windows are our transients?
147 std::string title, icon_title;
152 int old_bw; // client's borderwidth
155 min_width, min_height, // can not be resized smaller
156 max_width, max_height, // can not be resized larger
157 width_inc, height_inc, // increment step
158 #if 0 // not supported at the moment
159 min_aspect_x, min_aspect_y, // minimum aspect ratio
160 max_aspect_x, max_aspect_y, // maximum aspect ratio
162 base_width, base_height,
165 unsigned long initial_state, normal_hint_flags;
168 FunctionFlags functions;
170 * what decorations do we have?
171 * this is based on the type of the client window as well as user input
173 DecorationFlags decorations;
174 DecorationFlags mwm_decorations;
176 WindowType window_type;
179 * client window = the application's window
180 * frame window = the window drawn around the outside of the client window
181 * by the window manager which contains items like the
182 * titlebar and close button
183 * title = the titlebar drawn above the client window, it displays the
184 * window's name and any buttons for interacting with the window,
185 * such as iconify, maximize, and close
186 * label = the window in the titlebar where the title is drawn
187 * buttons = maximize, iconify, close
188 * handle = the bar drawn at the bottom of the window, which contains the
189 * left and right grips used for resizing the window
190 * grips = the smaller reactangles in the handle, one of each side of it.
191 * When clicked and dragged, these resize the window interactively
192 * border = the line drawn around the outside edge of the frame window,
193 * between the title, the bordered client window, and the handle.
194 * Also drawn between the grips and the handle
198 // u -> unfocused, f -> has focus, p -> pressed
199 unsigned long ulabel_pixel, flabel_pixel, utitle_pixel,
200 ftitle_pixel, uhandle_pixel, fhandle_pixel, ubutton_pixel,
201 fbutton_pixel, pfbutton_pixel, pubutton_pixel,
202 uborder_pixel, fborder_pixel, ugrip_pixel, fgrip_pixel;
203 Pixmap ulabel, flabel, utitle, ftitle, uhandle, fhandle,
204 ubutton, fbutton, pfbutton, pubutton, ugrip, fgrip;
206 Window window, // the frame
207 plate, // holds the client
211 close_button, iconify_button, maximize_button, stick_button,
212 right_grip, left_grip;
215 * size and location of the box drawn while the window dimensions or
216 * location is being changed, ie. resized or moved
220 otk::Rect rect; // frame geometry
221 Strut margin; // margins between the frame and client
223 int grab_x, grab_y; // where was the window when it was grabbed?
225 unsigned int inside_w, inside_h, // window w/h without border_w
226 title_h, label_w, label_h, handle_h,
227 button_w, grip_w, mwm_border_w, border_w,
231 BlackboxWindow(const BlackboxWindow&);
232 BlackboxWindow& operator=(const BlackboxWindow&);
235 Window createToplevelWindow();
236 Window createChildWindow(Window parent, unsigned long event_mask,
239 bool getWindowType(void);
240 void updateStrut(void);
241 void getWMName(void);
242 void getWMIconName(void);
243 void getWMNormalHints(void);
244 void getWMProtocols(void);
245 void getWMHints(void);
246 void getNetWMHints(void);
247 void getMWMHints(void);
248 bool getBlackboxHints(void);
249 void getTransientInfo(void);
250 void setNetWMAttributes(void);
251 void associateClientWindow(void);
253 void decorateLabel(void);
254 void positionButtons(bool redecorate_label = False);
255 void positionWindows(void);
256 void createHandle(void);
257 void destroyHandle(void);
258 void createTitlebar(void);
259 void destroyTitlebar(void);
260 void createCloseButton(void);
261 void destroyCloseButton(void);
262 void createIconifyButton(void);
263 void destroyIconifyButton(void);
264 void createMaximizeButton(void);
265 void destroyMaximizeButton(void);
266 void createStickyButton(void);
267 void destroyStickyButton(void);
268 void redrawWindowFrame(void) const;
269 void redrawLabel(void) const;
270 void redrawAllButtons(void) const;
271 void redrawButton(bool pressed, Window win,
272 Pixmap fppix, unsigned long fppixel,
273 Pixmap uppix, unsigned long uppixel,
274 Pixmap fpix, unsigned long fpixel,
275 Pixmap upix, unsigned long upixel) const;
276 void redrawCloseButton(bool pressed) const;
277 void redrawIconifyButton(bool pressed) const;
278 void redrawMaximizeButton(bool pressed) const;
279 void redrawStickyButton(bool pressed) const;
280 void applyGravity(otk::Rect &r);
281 void restoreGravity(otk::Rect &r);
282 void setAllowedActions(void);
283 void setState(unsigned long new_state);
285 void doMove(int x_root, int y_root);
286 void doWorkspaceWarping(int x_root, int y_root, int &dx);
287 void doWindowSnapping(int &dx, int &dy);
289 void doResize(int x_root, int y_root);
290 void endResize(void);
292 void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
295 BlackboxWindow(Blackbox *b, Window w, BScreen *s);
296 virtual ~BlackboxWindow(void);
298 inline bool isTransient(void) const { return client.transient_for != 0; }
299 inline bool isFocused(void) const { return flags.focused; }
300 inline bool isVisible(void) const { return flags.visible; }
301 inline bool isIconic(void) const { return flags.iconic; }
302 inline bool isShaded(void) const { return flags.shaded; }
303 inline bool isMaximized(void) const { return flags.maximized; }
304 inline bool isMaximizedHoriz(void) const { return flags.maximized == 3; }
305 inline bool isMaximizedVert(void) const { return flags.maximized == 2; }
306 inline bool isMaximizedFull(void) const { return flags.maximized == 1; }
307 inline bool isStuck(void) const { return flags.stuck; }
308 inline bool isModal(void) const { return flags.modal; }
309 inline bool isIconifiable(void) const { return functions & Func_Iconify; }
310 inline bool isMaximizable(void) const { return functions & Func_Maximize; }
311 inline bool isResizable(void) const { return functions & Func_Resize; }
312 inline bool isClosable(void) const { return functions & Func_Close; }
314 // is a 'normal' window? meaning, a standard client application
315 inline bool isNormal(void) const
316 { return window_type == Type_Dialog || window_type == Type_Normal ||
317 window_type == Type_Toolbar || window_type == Type_Utility; }
318 inline bool isTopmost(void) const
319 { return window_type == Type_Toolbar || window_type == Type_Utility; }
320 inline bool isDesktop(void) const { return window_type == Type_Desktop; }
322 inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; }
324 inline const BlackboxWindowList &getTransients(void) const
325 { return client.transientList; }
326 BlackboxWindow *getTransientFor(void) const;
328 inline BScreen *getScreen(void) const { return screen; }
330 inline Window getFrameWindow(void) const { return frame.window; }
331 inline Window getClientWindow(void) const { return client.window; }
332 inline Window getGroupWindow(void) const { return client.window_group; }
334 inline const char *getTitle(void) const
335 { return client.title.c_str(); }
336 inline const char *getIconTitle(void) const
337 { return client.icon_title.c_str(); }
339 inline unsigned int getWorkspaceNumber(void) const
340 { return blackbox_attrib.workspace; }
341 inline unsigned int getWindowNumber(void) const { return window_number; }
343 inline const otk::Rect &frameRect(void) const { return frame.rect; }
344 inline const otk::Rect &clientRect(void) const { return client.rect; }
346 inline unsigned int getTitleHeight(void) const
347 { return frame.title_h; }
349 inline void setWindowNumber(int n) { window_number = n; }
351 bool validateClient(void) const;
352 bool setInputFocus(void);
354 // none of these are used by the window manager, they are here to persist
355 // them properly in the window's netwm state property.
356 inline bool skipTaskbar(void) const { return flags.skip_taskbar; }
357 inline void setSkipTaskbar(const bool s) { flags.skip_taskbar = s; }
358 inline bool skipPager(void) const { return flags.skip_pager; }
359 inline void setSkipPager(const bool s) { flags.skip_pager = s; }
360 inline bool isFullscreen(void) const { return flags.fullscreen; }
361 inline void setFullscreen(const bool f) { flags.fullscreen = f; }
363 inline void setModal(const bool m) { flags.modal = m; }
365 void beginMove(int x_root, int y_root);
366 void beginResize(int x_root, int y_root, Corner dir);
367 void enableDecor(bool enable);
369 void setFocusFlag(bool focus);
371 void deiconify(bool reassoc = True, bool raise = True);
375 void maximize(unsigned int button);
376 void remaximize(void);
379 void reconfigure(void);
380 void grabButtons(void);
381 void ungrabButtons(void);
382 void installColormap(bool install);
383 void restore(bool remap);
384 void configure(int dx, int dy, unsigned int dw, unsigned int dh);
385 void setWorkspace(unsigned int n);
386 void changeBlackboxHints(const BlackboxHints *net);
387 void restoreAttributes(void);
389 void buttonPressEvent(const XButtonEvent *be);
390 void buttonReleaseEvent(const XButtonEvent *re);
391 void motionNotifyEvent(const XMotionEvent *me);
392 void destroyNotifyEvent(const XDestroyWindowEvent* /*unused*/);
393 void mapRequestEvent(const XMapRequestEvent *mre);
394 void unmapNotifyEvent(const XUnmapEvent* /*unused*/);
395 void reparentNotifyEvent(const XReparentEvent* /*unused*/);
396 void propertyNotifyEvent(const XPropertyEvent *pe);
397 void exposeEvent(const XExposeEvent *ee);
398 void configureRequestEvent(const XConfigureRequestEvent *cr);
399 void enterNotifyEvent(const XCrossingEvent *ce);
400 void leaveNotifyEvent(const XCrossingEvent* /*unused*/);
403 void configureShape(void);
404 void clearShape(void);
405 void shapeEvent(XShapeEvent * /*unused*/);
408 static void timeout(BlackboxWindow *t);
413 #endif // __Window_hh