Add the "obsetroot" tool. Use it to set the root background.
[dana/openbox.git] / src / frame.hh
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 #ifndef   __frame_hh
3 #define   __frame_hh
4
5 /*! @file frame.hh
6 */
7
8 extern "C" {
9 #include <X11/Xlib.h>
10 }
11
12 #include "client.hh"
13 #include "python.hh"
14 #include "otk/strut.hh"
15 #include "otk/rect.hh"
16 #include "otk/renderstyle.hh"
17 #include "otk/ustring.hh"
18 #include "otk/surface.hh"
19 #include "otk/eventhandler.hh"
20
21 #include <string>
22 #include <vector>
23
24 namespace ob {
25
26 //! Varius geometry settings in the frame decorations
27 struct FrameGeometry {
28   int width; // title and handle
29   int font_height;
30   int title_height() { return font_height + bevel*2; }
31   int label_width;
32   int label_height() { return font_height; }
33   int handle_height; // static, from the style
34   int icon_x;        // x-position of the window icon button
35   int handle_y;
36   int button_size;   // static, from the style
37   int grip_width() { return button_size * 2; }
38   int bevel;         // static, from the style
39   int bwidth;  // frame elements' border width
40   int cbwidth; // client border width
41 };
42
43 //! Holds and decorates a frame around an Client (client window)
44 /*!
45   The frame is responsible for calling XSelectInput on the client window's new
46   parent with the SubstructureRedirectMask so that structure events for the
47   client are sent to the window manager.
48 */
49 class Frame : public otk::StyleNotify, public otk::EventHandler {
50 public:
51
52   //! The event mask to grab on frame windows
53   static const long event_mask = EnterWindowMask | LeaveWindowMask;
54    
55 private:
56   Client *_client;
57
58   //! The size of the frame on each side of the client window
59   otk::Strut _size;
60
61   //! The size of the frame on each side of the client window inside the border
62   otk::Strut _innersize;
63
64   //! The position and size of the entire frame (including borders)
65   otk::Rect _area;
66
67   bool _visible;
68
69   //! The decorations that are being displayed in the frame.
70   Client::DecorationFlags _decorations;
71   
72   // decoration windows
73   Window  _frame;   // sits under everything
74   Window  _plate;   // sits entirely under the client window
75   Window  _title;   // the titlebar
76   Window  _label;   // the section of the titlebar which shows the window name
77   Window  _handle;  // bottom bar
78   Window  _lgrip;   // lefthand resize grab on the handle
79   Window  _rgrip;   // righthand resize grab on the handle
80   Window  _max;     // maximize button
81   Window  _desk;    // all-desktops button
82   Window  _iconify; // iconify button
83   Window  _icon;    // window icon button
84   Window  _close;   // close button
85
86   // surfaces for each 
87   otk::Surface  *_frame_sur;
88   otk::Surface  *_title_sur;
89   otk::Surface  *_label_sur;
90   otk::Surface  *_handle_sur;
91   otk::Surface  *_grip_sur;
92   otk::Surface  *_max_sur;
93   otk::Surface  *_desk_sur;
94   otk::Surface  *_iconify_sur;
95   otk::Surface  *_icon_sur;
96   otk::Surface  *_close_sur;
97
98   otk::ustring _layout; // layout of the titlebar
99
100   bool _max_press;
101   bool _desk_press;
102   bool _iconify_press;
103   bool _icon_press;
104   bool _close_press;
105   unsigned int _press_button; // mouse button that started the press
106
107   FrameGeometry geom;
108   
109   void applyStyle(const otk::RenderStyle &style);
110   void layoutTitle();
111   void renderLabel();
112   void renderMax();
113   void renderDesk();
114   void renderIconify();
115   void renderClose();
116   void renderIcon();
117
118 public:
119   //! Constructs an Frame object for a client
120   /*!
121     @param client The client which will be decorated by the new Frame
122   */
123   Frame(Client *client);
124   //! Destroys the Frame object
125   virtual ~Frame();
126
127   //! Returns the size of the frame on each side of the client
128   const otk::Strut& size() const { return _size; }
129   
130   //! Set the style to decorate the frame with
131   virtual void styleChanged(const otk::RenderStyle &style);
132
133   //! Reparents the client window from the root window onto the frame
134   void grabClient();
135   //! Reparents the client window back to the root window
136   void releaseClient();
137
138   //! Update the frame's size to match the client
139   void adjustSize();
140   //! Update the frame's position to match the client
141   void adjustPosition();
142   //! Shape the frame window to the client window
143   void adjustShape();
144   //! Update the frame to match the client's new state (for things like toggle
145   //! buttons, focus, and the title) XXX break this up
146   void adjustState();
147   void adjustFocus();
148   void adjustTitle();
149   void adjustIcon();
150
151   //! Applies gravity to the client's position to find where the frame should
152   //! be positioned.
153   /*!
154     @return The proper coordinates for the frame, based on the client.
155   */
156   void clientGravity(int &x, int &y);
157
158   //! Reversly applies gravity to the frame's position to find where the client
159   //! should be positioned.
160   /*!
161     @return The proper coordinates for the client, based on the frame.
162   */
163   void frameGravity(int &x, int &y);
164
165   //! The position and size of the frame window
166   inline const otk::Rect& area() const { return _area; }
167
168   //! Returns if the frame is visible
169   inline bool visible() const { return _visible; }
170
171   //! Shows the frame
172   void show();
173   //! Hides the frame
174   void hide();
175
176   void buttonPressHandler(const XButtonEvent &e);
177   void buttonReleaseHandler(const XButtonEvent &e);
178
179   //! Returns the MouseContext for the given window id
180   /*!
181     Returns '-1' if no valid mouse context exists in the frame for the given
182     id.
183   */
184   ob::MouseContext::MC mouseContext(Window win) const;
185
186   //! Gets the window id of the frame's base top-level parent
187   inline Window window() const { return _frame; }
188   //! Gets the window id of the client's parent window
189   inline Window plate() const { return _plate; }
190
191   //! Returns a null terminated array of the window ids that make up the
192   //! frame's decorations.
193   Window *allWindows() const;
194 };
195
196 }
197
198 #endif // __frame_hh