1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Window.hh for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
6 // Permission is hereby granted, free of charge, to any person obtaining a
7 // copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following conditions:
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 // DEALINGS IN THE SOFTWARE.
29 #include <X11/Xutil.h>
31 # include <X11/extensions/shape.h>
37 #include "basedisplay.hh"
41 #define MwmHintsFunctions (1l << 0)
42 #define MwmHintsDecorations (1l << 1)
44 #define MwmFuncAll (1l << 0)
45 #define MwmFuncResize (1l << 1)
46 #define MwmFuncMove (1l << 2)
47 #define MwmFuncIconify (1l << 3)
48 #define MwmFuncMaximize (1l << 4)
49 #define MwmFuncClose (1l << 5)
51 #define MwmDecorAll (1l << 0)
52 #define MwmDecorBorder (1l << 1)
53 #define MwmDecorHandle (1l << 2)
54 #define MwmDecorTitle (1l << 3)
55 #define MwmDecorMenu (1l << 4) // not used
56 #define MwmDecorIconify (1l << 5)
57 #define MwmDecorMaximize (1l << 6)
59 // this structure only contains 3 elements... the Motif 2.0 structure contains
60 // 5... we only need the first 3... so that is all we will define
61 typedef struct MwmHints {
62 unsigned long flags, functions, decorations;
65 #define PropMwmHintsElements 3
71 BlackboxWindowList windowList;
74 BWindowGroup(Blackbox *b, Window _group);
77 inline Window groupWindow(void) const { return group; }
79 inline bool empty(void) const { return windowList.empty(); }
81 void addWindow(BlackboxWindow *w) { windowList.push_back(w); }
82 void removeWindow(BlackboxWindow *w) { windowList.remove(w); }
85 find a window on the specified screen. the focused window (if any) is
86 checked first, otherwise the first matching window found is returned.
87 transients are returned only if allow_transients is True.
89 BlackboxWindow *find(BScreen *screen, bool allow_transients = False) const;
93 class BlackboxWindow : public TimeoutHandler {
95 enum Function { Func_Resize = (1l << 0),
96 Func_Move = (1l << 1),
97 Func_Iconify = (1l << 2),
98 Func_Maximize = (1l << 3),
99 Func_Close = (1l << 4) };
100 typedef unsigned char FunctionFlags;
102 enum Decoration { Decor_Titlebar = (1l << 0),
103 Decor_Handle = (1l << 1),
104 Decor_Border = (1l << 2),
105 Decor_Iconify = (1l << 3),
106 Decor_Maximize = (1l << 4),
107 Decor_Close = (1l << 5) };
108 typedef unsigned char DecorationFlags;
110 enum WindowType { Type_Desktop,
119 enum Corner { TopLeft,
129 BlackboxAttributes blackbox_attrib;
131 Time lastButtonPressTime; // used for double clicks, when were we clicked
133 unsigned int window_number;
134 unsigned long current_state;
135 unsigned int mod_mask; // the mod mask used to grab buttons
137 enum FocusMode { F_NoInput = 0, F_Passive,
138 F_LocallyActive, F_GloballyActive };
139 FocusMode focus_mode;
142 bool moving, // is moving?
143 resizing, // is resizing?
144 shaded, // is shaded?
145 visible, // is visible?
146 iconic, // is iconified?
147 focused, // has focus?
148 stuck, // is omnipresent?
149 modal, // is modal? (must be dismissed to continue)
150 skip_taskbar, // skipped by taskbars?
151 skip_pager, // skipped by pagers?
152 fullscreen, // a fullscreen window?
153 send_focus_message, // should we send focus messages to our client?
154 shaped; // does the frame use the shape extension?
155 unsigned int maximized; // maximize is special, the number corresponds
156 // with a mouse button
157 // if 0, not maximized
158 // 1 = HorizVert, 2 = Vertical, 3 = Horizontal
162 Window window, // the client's window
164 BlackboxWindow *transient_for; // which window are we a transient for?
165 BlackboxWindowList transientList; // which windows are our transients?
167 std::string title, icon_title;
172 int old_bw; // client's borderwidth
175 min_width, min_height, // can not be resized smaller
176 max_width, max_height, // can not be resized larger
177 width_inc, height_inc, // increment step
178 #if 0 // not supported at the moment
179 min_aspect_x, min_aspect_y, // minimum aspect ratio
180 max_aspect_x, max_aspect_y, // maximum aspect ratio
182 base_width, base_height,
185 unsigned long initial_state, normal_hint_flags;
188 FunctionFlags functions;
190 * what decorations do we have?
191 * this is based on the type of the client window as well as user input
193 DecorationFlags decorations;
194 DecorationFlags mwm_decorations;
196 WindowType window_type;
199 * client window = the application's window
200 * frame window = the window drawn around the outside of the client window
201 * by the window manager which contains items like the
202 * titlebar and close button
203 * title = the titlebar drawn above the client window, it displays the
204 * window's name and any buttons for interacting with the window,
205 * such as iconify, maximize, and close
206 * label = the window in the titlebar where the title is drawn
207 * buttons = maximize, iconify, close
208 * handle = the bar drawn at the bottom of the window, which contains the
209 * left and right grips used for resizing the window
210 * grips = the smaller reactangles in the handle, one of each side of it.
211 * When clicked and dragged, these resize the window interactively
212 * border = the line drawn around the outside edge of the frame window,
213 * between the title, the bordered client window, and the handle.
214 * Also drawn between the grips and the handle
218 // u -> unfocused, f -> has focus, p -> pressed
219 unsigned long ulabel_pixel, flabel_pixel, utitle_pixel,
220 ftitle_pixel, uhandle_pixel, fhandle_pixel, ubutton_pixel,
221 fbutton_pixel, pfbutton_pixel, pubutton_pixel,
222 uborder_pixel, fborder_pixel, ugrip_pixel, fgrip_pixel;
223 Pixmap ulabel, flabel, utitle, ftitle, uhandle, fhandle,
224 ubutton, fbutton, pfbutton, pubutton, ugrip, fgrip;
226 Window window, // the frame
227 plate, // holds the client
231 close_button, iconify_button, maximize_button, stick_button,
232 right_grip, left_grip;
235 * size and location of the box drawn while the window dimensions or
236 * location is being changed, ie. resized or moved
240 Rect rect; // frame geometry
241 Strut margin; // margins between the frame and client
243 int grab_x, grab_y; // where was the window when it was grabbed?
245 unsigned int inside_w, inside_h, // window w/h without border_w
246 title_h, label_w, label_h, handle_h,
247 button_w, grip_w, mwm_border_w, border_w,
251 BlackboxWindow(const BlackboxWindow&);
252 BlackboxWindow& operator=(const BlackboxWindow&);
255 Window createToplevelWindow();
256 Window createChildWindow(Window parent, unsigned long event_mask,
259 bool getWindowType(void);
260 void updateStrut(void);
261 void getWMName(void);
262 void getWMIconName(void);
263 void getWMNormalHints(void);
264 void getWMProtocols(void);
265 void getWMHints(void);
266 void getNetWMHints(void);
267 void getMWMHints(void);
268 bool getBlackboxHints(void);
269 void getTransientInfo(void);
270 void setNetWMAttributes(void);
271 void associateClientWindow(void);
273 void decorateLabel(void);
274 void positionButtons(bool redecorate_label = False);
275 void positionWindows(void);
276 void createHandle(void);
277 void destroyHandle(void);
278 void createTitlebar(void);
279 void destroyTitlebar(void);
280 void createCloseButton(void);
281 void destroyCloseButton(void);
282 void createIconifyButton(void);
283 void destroyIconifyButton(void);
284 void createMaximizeButton(void);
285 void destroyMaximizeButton(void);
286 void createStickyButton(void);
287 void destroyStickyButton(void);
288 void redrawWindowFrame(void) const;
289 void redrawLabel(void) const;
290 void redrawAllButtons(void) const;
291 void redrawButton(bool pressed, Window win,
292 Pixmap fppix, unsigned long fppixel,
293 Pixmap uppix, unsigned long uppixel,
294 Pixmap fpix, unsigned long fpixel,
295 Pixmap upix, unsigned long upixel) const;
296 void redrawCloseButton(bool pressed) const;
297 void redrawIconifyButton(bool pressed) const;
298 void redrawMaximizeButton(bool pressed) const;
299 void redrawStickyButton(bool pressed) const;
300 void applyGravity(Rect &r);
301 void restoreGravity(Rect &r);
302 void setAllowedActions(void);
303 void setState(unsigned long new_state);
305 void doMove(int x_root, int y_root);
306 void doWorkspaceWarping(int x_root, int y_root, int &dx);
307 void doWindowSnapping(int &dx, int &dy);
309 void doResize(int x_root, int y_root);
310 void endResize(void);
312 void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
315 BlackboxWindow(Blackbox *b, Window w, BScreen *s);
316 virtual ~BlackboxWindow(void);
318 inline bool isTransient(void) const { return client.transient_for != 0; }
319 inline bool isFocused(void) const { return flags.focused; }
320 inline bool isVisible(void) const { return flags.visible; }
321 inline bool isIconic(void) const { return flags.iconic; }
322 inline bool isShaded(void) const { return flags.shaded; }
323 inline bool isMaximized(void) const { return flags.maximized; }
324 inline bool isMaximizedHoriz(void) const { return flags.maximized == 3; }
325 inline bool isMaximizedVert(void) const { return flags.maximized == 2; }
326 inline bool isMaximizedFull(void) const { return flags.maximized == 1; }
327 inline bool isStuck(void) const { return flags.stuck; }
328 inline bool isModal(void) const { return flags.modal; }
329 inline bool isIconifiable(void) const { return functions & Func_Iconify; }
330 inline bool isMaximizable(void) const { return functions & Func_Maximize; }
331 inline bool isResizable(void) const { return functions & Func_Resize; }
332 inline bool isClosable(void) const { return functions & Func_Close; }
334 // is a 'normal' window? meaning, a standard client application
335 inline bool isNormal(void) const
336 { return window_type == Type_Dialog || window_type == Type_Normal ||
337 window_type == Type_Toolbar || window_type == Type_Utility; }
338 inline bool isTopmost(void) const
339 { return window_type == Type_Toolbar || window_type == Type_Utility; }
340 inline bool isDesktop(void) const { return window_type == Type_Desktop; }
342 inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; }
344 inline const BlackboxWindowList &getTransients(void) const
345 { return client.transientList; }
346 BlackboxWindow *getTransientFor(void) const;
348 inline BScreen *getScreen(void) const { return screen; }
350 inline Window getFrameWindow(void) const { return frame.window; }
351 inline Window getClientWindow(void) const { return client.window; }
352 inline Window getGroupWindow(void) const { return client.window_group; }
354 inline const char *getTitle(void) const
355 { return client.title.c_str(); }
356 inline const char *getIconTitle(void) const
357 { return client.icon_title.c_str(); }
359 inline unsigned int getWorkspaceNumber(void) const
360 { return blackbox_attrib.workspace; }
361 inline unsigned int getWindowNumber(void) const { return window_number; }
363 inline const Rect &frameRect(void) const { return frame.rect; }
364 inline const Rect &clientRect(void) const { return client.rect; }
366 inline unsigned int getTitleHeight(void) const
367 { return frame.title_h; }
369 inline void setWindowNumber(int n) { window_number = n; }
371 bool validateClient(void) const;
372 bool setInputFocus(void);
374 // none of these are used by the window manager, they are here to persist
375 // them properly in the window's netwm state property.
376 inline bool skipTaskbar(void) const { return flags.skip_taskbar; }
377 inline void setSkipTaskbar(const bool s) { flags.skip_taskbar = s; }
378 inline bool skipPager(void) const { return flags.skip_pager; }
379 inline void setSkipPager(const bool s) { flags.skip_pager = s; }
380 inline bool isFullscreen(void) const { return flags.fullscreen; }
381 inline void setFullscreen(const bool f) { flags.fullscreen = f; }
383 inline void setModal(const bool m) { flags.modal = m; }
385 void beginMove(int x_root, int y_root);
386 void beginResize(int x_root, int y_root, Corner dir);
387 void enableDecor(bool enable);
389 void setFocusFlag(bool focus);
391 void deiconify(bool reassoc = True, bool raise = True);
395 void maximize(unsigned int button);
396 void remaximize(void);
399 void reconfigure(void);
400 void grabButtons(void);
401 void ungrabButtons(void);
402 void installColormap(bool install);
403 void restore(bool remap);
404 void configure(int dx, int dy, unsigned int dw, unsigned int dh);
405 void setWorkspace(unsigned int n);
406 void changeBlackboxHints(const BlackboxHints *net);
407 void restoreAttributes(void);
409 void buttonPressEvent(const XButtonEvent *be);
410 void buttonReleaseEvent(const XButtonEvent *re);
411 void motionNotifyEvent(const XMotionEvent *me);
412 void destroyNotifyEvent(const XDestroyWindowEvent* /*unused*/);
413 void mapRequestEvent(const XMapRequestEvent *mre);
414 void unmapNotifyEvent(const XUnmapEvent* /*unused*/);
415 void reparentNotifyEvent(const XReparentEvent* /*unused*/);
416 void propertyNotifyEvent(const XPropertyEvent *pe);
417 void exposeEvent(const XExposeEvent *ee);
418 void configureRequestEvent(const XConfigureRequestEvent *cr);
419 void enterNotifyEvent(const XCrossingEvent *ce);
420 void leaveNotifyEvent(const XCrossingEvent* /*unused*/);
423 void configureShape(void);
424 void clearShape(void);
425 void shapeEvent(XShapeEvent * /*unused*/);
428 virtual void timeout(void);
432 #endif // __Window_hh