convert XAtom to OBAtom
[mikachu/openbox.git] / src / bbwindow.hh
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 #ifndef   __Window_hh
3 #define   __Window_hh
4
5 extern "C" {
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 #ifdef    SHAPE
9 #  include <X11/extensions/shape.h>
10 #endif // SHAPE
11 }
12
13 #include <string>
14
15 #include "otk/timer.hh"
16 #include "blackbox.hh"
17 #include "util.hh"
18
19 #define MwmHintsFunctions     (1l << 0)
20 #define MwmHintsDecorations   (1l << 1)
21
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)
28
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)
36
37 namespace ob {
38
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;
43 } MwmHints;
44
45 #define PropMwmHintsElements  3
46
47 class BWindowGroup {
48 private:
49   Blackbox *blackbox;
50   Window group;
51   BlackboxWindowList windowList;
52
53 public:
54   BWindowGroup(Blackbox *b, Window _group);
55   ~BWindowGroup(void);
56
57   inline Window groupWindow(void) const { return group; }
58
59   inline bool empty(void) const { return windowList.empty(); }
60
61   void addWindow(BlackboxWindow *w) { windowList.push_back(w); }
62   void removeWindow(BlackboxWindow *w) { windowList.remove(w); }
63
64   /*
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.
68   */
69   BlackboxWindow *find(BScreen *screen, bool allow_transients = False) const;
70 };
71
72
73 class BlackboxWindow {
74 public:
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;
81
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;
89
90   enum WindowType { Type_Desktop,
91                     Type_Dock,
92                     Type_Toolbar,
93                     Type_Menu,
94                     Type_Utility,
95                     Type_Splash,
96                     Type_Dialog,
97                     Type_Normal };
98
99   enum Corner { TopLeft,
100                 TopRight,
101                 BottomLeft,
102                 BottomRight };
103
104 private:
105   Blackbox *blackbox;
106   BScreen *screen;
107   OBAtom *xatom;
108   otk::OBTimer *timer;
109   BlackboxAttributes blackbox_attrib;
110
111   Time lastButtonPressTime;  // used for double clicks, when were we clicked
112
113   unsigned int window_number;
114   unsigned long current_state;
115   unsigned int mod_mask;    // the mod mask used to grab buttons
116
117   enum FocusMode { F_NoInput = 0, F_Passive,
118                    F_LocallyActive, F_GloballyActive };
119   FocusMode focus_mode;
120
121   struct _flags {
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
139   } flags;
140
141   struct _client {
142     Window window,                  // the client's window
143       window_group;
144     BlackboxWindow *transient_for;  // which window are we a transient for?
145     BlackboxWindowList transientList; // which windows are our transients?
146
147     std::string title, icon_title;
148
149     otk::Rect rect;
150     Strut strut;
151
152     int old_bw;                       // client's borderwidth
153
154     unsigned int
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
161 #endif
162       base_width, base_height,
163       win_gravity;
164
165     unsigned long initial_state, normal_hint_flags;
166   } client;
167
168   FunctionFlags functions;
169   /*
170    * what decorations do we have?
171    * this is based on the type of the client window as well as user input
172    */
173   DecorationFlags decorations;
174   DecorationFlags mwm_decorations;
175   Corner resize_dir;
176   WindowType window_type;
177
178   /*
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
195    */
196
197   struct _frame {
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;
205
206     Window window,       // the frame
207       plate,             // holds the client
208       title,
209       label,
210       handle,
211       close_button, iconify_button, maximize_button, stick_button,
212       right_grip, left_grip;
213
214     /*
215      * size and location of the box drawn while the window dimensions or
216      * location is being changed, ie. resized or moved
217      */
218     otk::Rect changing;
219
220     otk::Rect rect;                  // frame geometry
221     Strut margin;               // margins between the frame and client
222
223     int grab_x, grab_y;         // where was the window when it was grabbed?
224
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,
228       bevel_w;
229   } frame;
230
231   BlackboxWindow(const BlackboxWindow&);
232   BlackboxWindow& operator=(const BlackboxWindow&);
233
234   bool getState(void);
235   Window createToplevelWindow();
236   Window createChildWindow(Window parent, unsigned long event_mask,
237                            Cursor = None);
238
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);
252   void decorate(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);
284   void upsize(void);
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);
288   void endMove(void);
289   void doResize(int x_root, int y_root);
290   void endResize(void);
291
292   void constrain(Corner anchor, unsigned int *pw = 0, unsigned int *ph = 0);
293
294 public:
295   BlackboxWindow(Blackbox *b, Window w, BScreen *s);
296   virtual ~BlackboxWindow(void);
297
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; }
313
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; }
321   
322   inline bool hasTitlebar(void) const { return decorations & Decor_Titlebar; }
323
324   inline const BlackboxWindowList &getTransients(void) const
325   { return client.transientList; }
326   BlackboxWindow *getTransientFor(void) const;
327
328   inline BScreen *getScreen(void) const { return screen; }
329
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; }
333
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(); }
338
339   inline unsigned int getWorkspaceNumber(void) const
340   { return blackbox_attrib.workspace; }
341   inline unsigned int getWindowNumber(void) const { return window_number; }
342
343   inline const otk::Rect &frameRect(void) const { return frame.rect; }
344   inline const otk::Rect &clientRect(void) const { return client.rect; }
345
346   inline unsigned int getTitleHeight(void) const
347   { return frame.title_h; }
348
349   inline void setWindowNumber(int n) { window_number = n; }
350
351   bool validateClient(void) const;
352   bool setInputFocus(void);
353
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; }
362
363   inline void setModal(const bool m) { flags.modal = m; }
364
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);
368   void setupDecor();
369   void setFocusFlag(bool focus);
370   void iconify(void);
371   void deiconify(bool reassoc = True, bool raise = True);
372   void show(void);
373   void close(void);
374   void withdraw(void);
375   void maximize(unsigned int button);
376   void remaximize(void);
377   void shade(void);
378   void stick(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);
388
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*/);
401
402 #ifdef    SHAPE
403   void configureShape(void);
404   void clearShape(void);
405   void shapeEvent(XShapeEvent * /*unused*/);
406 #endif // SHAPE
407
408   static void timeout(BlackboxWindow *t);
409 };
410
411 }
412
413 #endif // __Window_hh