]> icculus.org git repositories - mikachu/openbox.git/blob - src/client.hh
handle configure requests
[mikachu/openbox.git] / src / client.hh
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 #ifndef   __client_hh
3 #define   __client_hh
4
5 /*! @file client.hh
6   @brief The OBClient class maintains the state of a client window by handling
7   property changes on the window and some client messages
8 */
9
10 extern "C" {
11 #include <X11/Xlib.h>
12
13 #ifdef    SHAPE
14 #include <X11/extensions/shape.h>
15 #endif // SHAPE
16 }
17
18 #include <string>
19
20 #include "otk/point.hh"
21 #include "otk/strut.hh"
22 #include "otk/rect.hh"
23 #include "otk/eventhandler.hh"
24
25 namespace ob {
26
27 class OBFrame;
28
29 //! Maintains the state of a client window.
30 /*!
31   OBClient maintains the state of a client window. The state consists of the
32   hints that the application sets on the window, such as the title, or window
33   gravity.
34   <p>
35   OBClient also manages client messages for the client window. When the
36   application (or any application) requests something to be changed for the
37   client, it will call the ActionHandler (for client messages) or update the
38   class' member variables and call whatever is nessary to complete the
39   change (such as causing a redraw of the titlebar after the title is changed).
40 */
41 class OBClient : public otk::OtkEventHandler {
42 public:
43
44   //! The frame window which decorates around the client window
45   /*!
46     NOTE: This should NEVER be used inside the client class's constructor!
47   */
48   OBFrame *frame;
49
50   //! Corners of the client window, used for anchor positions
51   enum Corner { TopLeft,
52                 TopRight,
53                 BottomLeft,
54                 BottomRight };
55
56   //! Possible window types
57   enum WindowType { Type_Desktop, //!< A desktop (bottom-most window)
58                     Type_Dock,    //!< A dock bar/panel window
59                     Type_Toolbar, //!< A toolbar window, pulled off an app
60                     Type_Menu,    //!< A sticky menu from an app
61                     Type_Utility, //!< A small utility window such as a palette
62                     Type_Splash,  //!< A splash screen window
63                     Type_Dialog,  //!< A dialog window
64                     Type_Normal   //!< A normal application window
65   };
66
67   //! Possible flags for MWM Hints (defined by Motif 2.0)
68   enum MwmFlags { MwmFlag_Functions   = 1 << 0, //!< The MMW Hints define funcs
69                   MwmFlag_Decorations = 1 << 1  //!< The MWM Hints define decor
70   };
71
72   //! Possible functions for MWM Hints (defined by Motif 2.0)
73   enum MwmFunctions { MwmFunc_All      = 1 << 0, //!< All functions
74                       MwmFunc_Resize   = 1 << 1, //!< Allow resizing
75                       MwmFunc_Move     = 1 << 2, //!< Allow moving
76                       MwmFunc_Iconify  = 1 << 3, //!< Allow to be iconfied
77                       MwmFunc_Maximize = 1 << 4  //!< Allow to be maximized
78                       //MwmFunc_Close    = 1 << 5 //!< Allow to be closed
79   };
80
81   //! Possible decorations for MWM Hints (defined by Motif 2.0)
82   enum MemDecorations { MwmDecor_All      = 1 << 0, //!< All decorations
83                         MwmDecor_Border   = 1 << 1, //!< Show a border
84                         MwmDecor_Handle   = 1 << 2, //!< Show a handle (bottom)
85                         MwmDecor_Title    = 1 << 3, //!< Show a titlebar
86                         //MwmDecor_Menu     = 1 << 4, //!< Show a menu
87                         MwmDecor_Iconify  = 1 << 5, //!< Show an iconify button
88                         MwmDecor_Maximize = 1 << 6  //!< Show a maximize button
89   };
90
91   //! The things the user can do to the client window
92   enum Function { Func_Resize   = 1 << 0, //!< Allow resizing
93                   Func_Move     = 1 << 1, //!< Allow moving
94                   Func_Iconify  = 1 << 2, //!< Allow to be iconified
95                   Func_Maximize = 1 << 3, //!< Allow to be maximized
96                   Func_Close    = 1 << 4  //!< Allow to be closed
97   };
98   //! Holds a bitmask of OBClient::Function values
99   typedef unsigned char FunctionFlags;
100
101   //! The decorations the client window wants to be displayed on it
102   enum Decoration { Decor_Titlebar = 1 << 0, //!< Display a titlebar
103                     Decor_Handle   = 1 << 1, //!< Display a handle (bottom)
104                     Decor_Border   = 1 << 2, //!< Display a border
105                     Decor_Iconify  = 1 << 3, //!< Display an iconify button
106                     Decor_Maximize = 1 << 4, //!< Display a maximize button
107                     Decor_Sticky   = 1 << 5, //!< Display a sticky button
108                     Decor_Close    = 1 << 6  //!< Display a close button
109   };
110   //! Holds a bitmask of OBClient::Decoration values
111   typedef unsigned char DecorationFlags;
112
113   //! The MWM Hints as retrieved from the window property
114   /*!
115     This structure only contains 3 elements, even though the Motif 2.0
116     structure contains 5. We only use the first 3, so that is all gets defined.
117   */
118   typedef struct MwmHints {
119     //! The number of elements in the OBClient::MwmHints struct
120     static const unsigned int elements = 3;
121     unsigned long flags;      //!< A bitmask of OBClient::MwmFlags values
122     unsigned long functions;  //!< A bitmask of OBClient::MwmFunctions values
123     unsigned long decorations;//!< A bitmask of OBClient::MwmDecorations values
124   };
125
126   //! Possible actions that can be made with the _NET_WM_STATE client message
127   enum StateAction { State_Remove = 0, //!< _NET_WM_STATE_REMOVE
128                      State_Add,        //!< _NET_WM_STATE_ADD
129                      State_Toggle      //!< _NET_WM_STATE_TOGGLE
130   };
131
132   //! The event mask to grab on client windows
133   static const long event_mask = PropertyChangeMask | FocusChangeMask;
134
135   //! The number of unmap events to ignore on the window
136   int ignore_unmaps;
137   
138 private:
139   //! The screen number on which the client resides
140   int      _screen;
141   
142   //! The actual window that this class is wrapping up
143   Window   _window;
144
145   //! The id of the group the window belongs to
146   Window   _group;
147
148   // XXX: transient_for, transients
149
150   //! The desktop on which the window resides (0xffffffff for all desktops)
151   unsigned long _desktop;
152
153   //! Normal window title
154   std::string  _title; // XXX: Have to keep track if this string is Utf8 or not
155   //! Window title when iconifiged
156   std::string  _icon_title;
157
158   //! The application that created the window
159   std::string  _app_name;
160   //! The class of the window, can used for grouping
161   std::string  _app_class;
162
163   //! The type of window (what its function is)
164   WindowType   _type;
165
166   //! Position and size of the window
167   /*!
168     This will not always be the actual position of the window on screen, it is
169     rather, the position requested by the client, to which the window's gravity
170     is applied.
171   */
172   otk::Rect    _area;
173
174   //! The logical size of the window
175   /*!
176     The "logical" size of the window is refers to the user's perception of the
177     size of the window, and is the value that should be displayed to the user.
178     For example, with xterms, this value it the number of characters being
179     displayed in the terminal, instead of the number of pixels.
180   */
181   otk::Point   _logical_size;
182
183   //! Width of the border on the window.
184   /*!
185     The window manager will set this to 0 while the window is being managed,
186     but needs to restore it afterwards, so it is saved here.
187   */
188   int _border_width;
189
190   //! The minimum size of the client window
191   /*!
192     If the min is > the max, then the window is not resizable
193   */
194   otk::Point _min_size;
195   //! The maximum size of the client window
196   /*!
197     If the min is > the max, then the window is not resizable
198   */
199   otk::Point _max_size;
200   //! The size of increments to resize the client window by
201   otk::Point _size_inc;
202   //! The base size of the client window
203   /*!
204     This value should be subtracted from the window's actual size when
205     displaying its size to the user, or working with its min/max size
206   */
207   otk::Point _base_size;
208
209   //! Where to place the decorated window in relation to the undecorated window
210   int _gravity;
211
212   //! The state of the window, one of WithdrawnState, IconicState, or
213   //! NormalState
214   long _wmstate;
215
216   //! Was the window's position requested by the application? if not, we should
217   //! place the window ourselves when it first appears
218   bool _positioned;
219   
220   //! Can the window receive input focus?
221   bool _can_focus;
222   //! Urgency flag
223   bool _urgent;
224   //! Notify the window when it receives focus?
225   bool _focus_notify;
226
227   //! The window uses shape extension to be non-rectangular?
228   bool _shaped;
229
230   //! The window is modal, so it must be processed before any windows it is
231   //! related to can be focused
232   bool _modal;
233   //! Only the window's titlebar is displayed
234   bool _shaded;
235   //! The window is iconified
236   bool _iconic;
237   //! The window is maximized to fill the screen vertically
238   bool _max_vert;
239   //! The window is maximized to fill the screen horizontally
240   bool _max_horz;
241   //! The window is a 'fullscreen' window, and should be on top of all others
242   bool _fullscreen;
243   //! The window should be on top of other windows of the same type
244   bool _floating;
245
246   //! A bitmask of values in the OBClient::Decoration enum
247   /*!
248     The values in the variable are the decorations that the client wants to be
249     displayed around it.
250   */
251   DecorationFlags _decorations;
252
253   //! A bitmask of values in the OBClient::Function enum
254   /*!
255     The values in the variable specify the ways in which the user is allowed to
256     modify this window.
257   */
258   FunctionFlags _functions;
259
260   //! Retrieves the desktop hint's value and sets OBClient::_desktop
261   void getDesktop();
262   //! Retrieves the window's type and sets OBClient::_type
263   void getType();
264   //! Gets the MWM Hints and adjusts OBClient::_functions and
265   //! OBClient::_decorations
266   void getMwmHints();
267   //! Gets the position and size of the window and sets OBClient::_area
268   void getArea();
269   //! Gets the net_state hint and sets the boolean flags for any states set in
270   //! the hint
271   void getState();
272   //! Determines if the window uses the Shape extension and sets
273   //! OBClient::_shaped
274   void getShaped();
275
276   //! Sets the wm_state to the specified value
277   void setWMState(long state);
278   //! Sends the window to the specified desktop
279   void setDesktop(long desktop);
280   //! Adjusts the window's net_state
281   void setState(StateAction action, long data1, long data2);
282
283   //! Update the protocols that the window supports and adjusts things if they
284   //! change
285   void updateProtocols();
286   //! Updates the WMNormalHints and adjusts things if they change
287   void updateNormalHints();
288   //! Updates the WMHints and adjusts things if they change
289   void updateWMHints();
290   //! Updates the window's title
291   void updateTitle();
292   //! Updates the window's icon title
293   void updateIconTitle();
294   //! Updates the window's application name and class
295   void updateClass();
296   // XXX: updateTransientFor();
297
298   //! Move the client window
299   /*!
300     This shouldnt be used to move the window internally! It will apply
301     window gravity after moving the window.
302   */
303   void move(int x, int y);
304   
305   //! Resizes the client window, anchoring it in a given corner
306   /*!
307     This also maintains things like the client's minsize, and size increments.
308     @param anchor The corner to keep in the same position when resizing
309     @param size The new size for the client
310   */
311   void resize(Corner anchor, int x, int y);
312   
313 public:
314   //! Constructs a new OBClient object around a specified window id
315   /*!
316     @param window The window id that the OBClient class should handle
317     @param screen The screen on which the window resides
318   */
319   OBClient(int screen, Window window);
320   //! Destroys the OBClient object
321   virtual ~OBClient();
322
323   //! Returns the screen on which the clien resides
324   inline int screen() const { return _screen; }
325   
326   //! Returns the window id that the OBClient object is handling
327   inline Window window() const { return _window; }
328
329   //! Returns the type of the window, one of the OBClient::WindowType values
330   inline WindowType type() const { return _type; }
331   //! Returns the desktop on which the window resides
332   /*!
333     This value is a 0-based index.<br>
334     A value of 0xffffffff indicates that the window exists on all desktops.
335   */
336   inline unsigned long desktop() const { return _desktop; }
337   //! Returns the window's title
338   inline const std::string &title() const { return _title; }
339   //! Returns the window's title when it is iconified
340   inline const std::string &iconTitle() const { return _title; }
341   //! Returns the application's name to whom the window belongs
342   inline const std::string &appName() const { return _app_name; }
343   //! Returns the class of the window
344   inline const std::string &appClass() const { return _app_class; }
345   //! Returns if the window can be focused
346   /*!
347     @return true if the window can receive focusl otherwise, false
348   */
349   inline bool canFocus() const { return _can_focus; }
350   //! Returns if the window has indicated that it needs urgent attention
351   inline bool urgent() const { return _urgent; }
352   //! Returns if the window wants to be notified when it receives focus
353   inline bool focusNotify() const { return _focus_notify; }
354   //! Returns if the window uses the Shape extension
355   inline bool shaped() const { return _shaped; }
356   //! Returns the window's gravity
357   /*!
358     This value determines where to place the decorated window in relation to
359     its position without decorations.<br>
360     One of: NorthWestGravity, SouthWestGravity, EastGravity, ...,
361     SouthGravity, StaticGravity, ForgetGravity
362   */
363   inline int gravity() const { return _gravity; }
364   //! Returns if the application requested the initial position for the window
365   /*!
366     If the application did not request a position (this function returns false)
367     then the window should be placed intelligently by the window manager
368     initially
369   */
370   inline bool positionRequested() const { return _positioned; }
371   //! Returns the decorations that the client window wishes to be displayed on
372   //! it
373   inline DecorationFlags decorations() const { return _decorations; }
374   //! Returns the functions that the user can perform on the window
375   inline FunctionFlags funtions() const { return _functions; }
376
377   //! Returns if the window is modal
378   /*!
379     If the window is modal, then no other windows that it is related to can get
380     focus while it exists/remains modal.
381   */
382   inline bool modal() const { return _modal; }
383   //! Returns if the window is shaded
384   /*!
385     When the window is shaded, only its titlebar is visible, the client itself
386     is not mapped
387   */
388   inline bool shaded() const { return _shaded; }
389   //! Returns if the window is iconified
390   /*!
391     When the window is iconified, it is not visible at all (except in iconbars/
392     panels/etc that want to show lists of iconified windows
393   */
394   inline bool iconic() const { return _iconic; }
395   //! Returns if the window is maximized vertically
396   inline bool maxVert() const { return _max_vert; }
397   //! Returns if the window is maximized horizontally
398   inline bool maxHorz() const { return _max_horz; }
399   //! Returns if the window is fullscreen
400   /*!
401     When the window is fullscreen, it is kept above all others
402   */
403   inline bool fullscreen() const { return _fullscreen; }
404   //! Returns if the window is floating
405   /*!
406     When the window is floating, it is kept above all others in the same
407     stacking layer as it
408   */
409   inline bool floating() const { return _floating; }
410
411   //! Returns the client's requested border width (not used by the wm)
412   inline int borderWidth() const { return _border_width; }
413
414   //! Returns the position and size of the client relative to the root window
415   inline const otk::Rect &area() const { return _area; }
416
417   virtual void propertyHandler(const XPropertyEvent &e);
418
419   virtual void clientMessageHandler(const XClientMessageEvent &e);
420
421   virtual void shapeHandler(const XShapeEvent &e);
422   
423   virtual void configureRequestHandler(const XConfigureRequestEvent &e);
424 };
425
426 }
427
428 #endif // __client_hh