]> icculus.org git repositories - dana/openbox.git/blob - src/window.hh
compiles now. uses xft2
[dana/openbox.git] / src / window.hh
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)
5 //
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:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
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.
23
24 #ifndef   __Window_hh
25 #define   __Window_hh
26
27 extern "C" {
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #ifdef    SHAPE
31 #  include <X11/extensions/shape.h>
32 #endif // SHAPE
33 }
34
35 #include <string>
36
37 #include "basedisplay.hh"
38 #include "timer.hh"
39 #include "util.hh"
40
41 #define MwmHintsFunctions     (1l << 0)
42 #define MwmHintsDecorations   (1l << 1)
43
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)
50
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)
58
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;
63 } MwmHints;
64
65 #define PropMwmHintsElements  3
66
67 class BWindowGroup {
68 private:
69   Blackbox *blackbox;
70   Window group;
71   BlackboxWindowList windowList;
72
73 public:
74   BWindowGroup(Blackbox *b, Window _group);
75   ~BWindowGroup(void);
76
77   inline Window groupWindow(void) const { return group; }
78
79   inline bool empty(void) const { return windowList.empty(); }
80
81   void addWindow(BlackboxWindow *w) { windowList.push_back(w); }
82   void removeWindow(BlackboxWindow *w) { windowList.remove(w); }
83
84   /*
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.
88   */
89   BlackboxWindow *find(BScreen *screen, bool allow_transients = False) const;
90 };
91
92
93 class BlackboxWindow : public TimeoutHandler {
94 public:
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;
101
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;
109
110   enum WindowType { Type_Desktop,
111                     Type_Dock,
112                     Type_Toolbar,
113                     Type_Menu,
114                     Type_Utility,
115                     Type_Splash,
116                     Type_Dialog,
117                     Type_Normal };
118
119   enum Corner { TopLeft,
120                 TopRight,
121                 BottomLeft,
122                 BottomRight };
123
124 private:
125   Blackbox *blackbox;
126   BScreen *screen;
127   XAtom *xatom;
128   BTimer *timer;
129   BlackboxAttributes blackbox_attrib;
130
131   Time lastButtonPressTime;  // used for double clicks, when were we clicked
132
133   unsigned int window_number;
134   unsigned long current_state;
135   unsigned int mod_mask;    // the mod mask used to grab buttons
136
137   enum FocusMode { F_NoInput = 0, F_Passive,
138                    F_LocallyActive, F_GloballyActive };
139   FocusMode focus_mode;
140
141   struct _flags {
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
159   } flags;
160
161   struct _client {
162     Window window,                  // the client's window
163       window_group;
164     BlackboxWindow *transient_for;  // which window are we a transient for?
165     BlackboxWindowList transientList; // which windows are our transients?
166
167     std::string title, icon_title;
168
169     Rect rect;
170     Strut strut;
171
172     int old_bw;                       // client's borderwidth
173
174     unsigned int
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
181 #endif
182       base_width, base_height,
183       win_gravity;
184
185     unsigned long initial_state, normal_hint_flags;
186   } client;
187
188   FunctionFlags functions;
189   /*
190    * what decorations do we have?
191    * this is based on the type of the client window as well as user input
192    */
193   DecorationFlags decorations;
194   DecorationFlags mwm_decorations;
195   Corner resize_dir;
196   WindowType window_type;
197
198   /*
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
215    */
216
217   struct _frame {
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;
225
226     Window window,       // the frame
227       plate,             // holds the client
228       title,
229       label,
230       handle,
231       close_button, iconify_button, maximize_button, stick_button,
232       right_grip, left_grip;
233
234     /*
235      * size and location of the box drawn while the window dimensions or
236      * location is being changed, ie. resized or moved
237      */
238     Rect changing;
239
240     Rect rect;                  // frame geometry
241     Strut margin;               // margins between the frame and client
242
243     int grab_x, grab_y;         // where was the window when it was grabbed?
244
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,
248       bevel_w;
249   } frame;
250
251   BlackboxWindow(const BlackboxWindow&);
252   BlackboxWindow& operator=(const BlackboxWindow&);
253
254   bool getState(void);
255   Window createToplevelWindow();
256   Window createChildWindow(Window parent, unsigned long event_mask,
257                            Cursor = None);
258
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);
272   void decorate(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);
304   void upsize(void);
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);
308   void endMove(void);
309   void doResize(int x_root, int y_root);
310   void endResize(void);
311
312   void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
313
314 public:
315   BlackboxWindow(Blackbox *b, Window w, BScreen *s);
316   virtual ~BlackboxWindow(void);
317
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; }
333
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; }
341   
342   inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; }
343
344   inline const BlackboxWindowList &getTransients(void) const
345   { return client.transientList; }
346   BlackboxWindow *getTransientFor(void) const;
347
348   inline BScreen *getScreen(void) const { return screen; }
349
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; }
353
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(); }
358
359   inline unsigned int getWorkspaceNumber(void) const
360   { return blackbox_attrib.workspace; }
361   inline unsigned int getWindowNumber(void) const { return window_number; }
362
363   inline const Rect &frameRect(void) const { return frame.rect; }
364   inline const Rect &clientRect(void) const { return client.rect; }
365
366   inline unsigned int getTitleHeight(void) const
367   { return frame.title_h; }
368
369   inline void setWindowNumber(int n) { window_number = n; }
370
371   bool validateClient(void) const;
372   bool setInputFocus(void);
373
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; }
382
383   inline void setModal(const bool m) { flags.modal = m; }
384
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);
388   void setupDecor();
389   void setFocusFlag(bool focus);
390   void iconify(void);
391   void deiconify(bool reassoc = True, bool raise = True);
392   void show(void);
393   void close(void);
394   void withdraw(void);
395   void maximize(unsigned int button);
396   void remaximize(void);
397   void shade(void);
398   void stick(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);
408
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*/);
421
422 #ifdef    SHAPE
423   void configureShape(void);
424   void clearShape(void);
425   void shapeEvent(XShapeEvent * /*unused*/);
426 #endif // SHAPE
427
428   virtual void timeout(void);
429 };
430
431
432 #endif // __Window_hh