]> icculus.org git repositories - dana/openbox.git/blob - src/frame.hh
split the move and resize on the client window
[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 "python.hh"
13 #include "otk/strut.hh"
14 #include "otk/rect.hh"
15 #include "otk/renderstyle.hh"
16 #include "otk/ustring.hh"
17 #include "otk/surface.hh"
18 #include "otk/eventhandler.hh"
19
20 #include <string>
21
22 namespace ob {
23
24 class Client;
25
26 //! Varius geometry settings in the frame decorations
27 struct FrameGeometry {
28   unsigned int width; // title and handle
29   unsigned int font_height;
30   unsigned int title_height() { return font_height + bevel*2; }
31   unsigned int label_width;
32   unsigned int label_height() { return font_height; }
33   unsigned int handle_height; // static, from the style
34   int handle_y;
35   unsigned int button_size;   // static, from the style
36   unsigned  grip_width() { return button_size * 2; }
37   unsigned  bevel;         // static, from the style
38   unsigned  bwidth;  // frame elements' border width
39   unsigned  cbwidth; // client border width
40 };
41
42 //! Holds and decorates a frame around an Client (client window)
43 /*!
44   The frame is responsible for calling XSelectInput on the client window's new
45   parent with the SubstructureRedirectMask so that structure events for the
46   client are sent to the window manager.
47 */
48 class Frame : public otk::StyleNotify, public otk::EventHandler {
49 public:
50
51   //! The event mask to grab on frame windows
52   static const long event_mask = EnterWindowMask | LeaveWindowMask;
53    
54 private:
55   Client *_client;
56
57   //! The size of the frame on each side of the client window
58   otk::Strut _size;
59
60   //! The size of the frame on each side of the client window inside the border
61   otk::Strut _innersize;
62
63   //! The position and size of the entire frame (including borders)
64   otk::Rect _area;
65
66   bool _visible;
67   
68   // decoration windows
69   Window  _frame;   // sits under everything
70   Window  _plate;   // sits entirely under the client window
71   Window  _title;   // the titlebar
72   Window  _label;   // the section of the titlebar which shows the window name
73   Window  _handle;  // bottom bar
74   Window  _lgrip;   // lefthand resize grab on the handle
75   Window  _rgrip;   // righthand resize grab on the handle
76   Window *_buttons; // all of the titlebar buttons
77   unsigned int  _numbuttons; // number of buttons, size of _buttons array
78   unsigned int *_titleorder; // order of the buttons and the label (always
79                              // holds '_numbuttons + 1' elements (for the
80                              // label, which is coded as '-1')
81
82   // surfaces for each 
83   otk::Surface  *_frame_sur;
84   otk::Surface  *_title_sur;
85   otk::Surface  *_label_sur;
86   otk::Surface  *_handle_sur;
87   otk::Surface  *_grip_sur;
88   otk::Surface **_buttons_sur;
89
90   FrameGeometry geom;
91   
92   void applyStyle(const otk::RenderStyle &style);
93   void layoutTitle();
94   void renderLabel();
95
96 public:
97   //! Constructs an Frame object for a client
98   /*!
99     @param client The client which will be decorated by the new Frame
100   */
101   Frame(Client *client);
102   //! Destroys the Frame object
103   virtual ~Frame();
104
105   //! Returns the size of the frame on each side of the client
106   const otk::Strut& size() const { return _size; }
107   
108   //! Set the style to decorate the frame with
109   virtual void styleChanged(const otk::RenderStyle &style);
110
111   //! Reparents the client window from the root window onto the frame
112   void grabClient();
113   //! Reparents the client window back to the root window
114   void releaseClient();
115
116   //! Update the frame's size to match the client
117   void adjustSize();
118   //! Update the frame's position to match the client
119   void adjustPosition();
120   //! Shape the frame window to the client window
121   void adjustShape();
122   //! Update the frame to match the client's new state (for things like toggle
123   //! buttons, focus, and the title) XXX break this up
124   void adjustState();
125   void adjustFocus();
126   void adjustTitle();
127
128   //! Applies gravity to the client's position to find where the frame should
129   //! be positioned.
130   /*!
131     @return The proper coordinates for the frame, based on the client.
132   */
133   void clientGravity(int &x, int &y);
134
135   //! Reversly applies gravity to the frame's position to find where the client
136   //! should be positioned.
137   /*!
138     @return The proper coordinates for the client, based on the frame.
139   */
140   void frameGravity(int &x, int &y);
141
142   //! The position and size of the frame window
143   inline const otk::Rect& area() const { return _area; }
144
145   //! Returns if the frame is visible
146   inline bool visible() const { return _visible; }
147
148   //! Shows the frame
149   void show();
150   //! Hides the frame
151   void hide();
152
153   //! Returns the MouseContext for the given window id
154   /*!
155     Returns '-1' if no valid mouse context exists in the frame for the given
156     id.
157   */
158   ob::MouseContext::MC mouseContext(Window win) const;
159
160   //! Gets the window id of the frame's base top-level parent
161   inline Window window() const { return _frame; }
162   //! Gets the window id of the client's parent window
163   inline Window plate() const { return _plate; }
164
165   //! Returns a null terminated array of the window ids that make up the
166   //! frame's decorations.
167   Window *allWindows() const;
168 };
169
170 }
171
172 #endif // __frame_hh