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