make window placement not go off screen at all
[mikachu/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 "backgroundwidget.hh"
14 #include "labelwidget.hh"
15 #include "buttonwidget.hh"
16 #include "otk/strut.hh"
17 #include "otk/rect.hh"
18 #include "otk/screeninfo.hh"
19 #include "otk/style.hh"
20 #include "otk/widget.hh"
21 #include "otk/ustring.hh"
22
23 #include <string>
24
25 namespace ob {
26
27 //! Holds and decorates a frame around an Client (client window)
28 /*!
29   The frame is responsible for calling XSelectInput on the client window's new
30   parent with the SubstructureRedirectMask so that structure events for the
31   client are sent to the window manager.
32 */
33 class Frame : public otk::Widget, public WidgetBase {
34 public:
35
36   //! The event mask to grab on frame windows
37   static const long event_mask = EnterWindowMask | LeaveWindowMask;
38    
39 private:
40   Client *_client;
41   const otk::ScreenInfo *_screen;
42
43   //! The size of the frame on each side of the client window
44   otk::Strut _size;
45
46   //! The size of the frame on each side of the client window inside the border
47   otk::Strut _innersize;
48
49   // decoration windows
50   BackgroundWidget  _plate;   // sits entirely under the client window
51   BackgroundWidget  _titlebar;
52   ButtonWidget      _button_close;
53   ButtonWidget      _button_iconify;
54   ButtonWidget      _button_max;
55   ButtonWidget      _button_stick;
56   LabelWidget       _label;
57   BackgroundWidget  _handle;
58   ButtonWidget      _grip_left;
59   ButtonWidget      _grip_right;
60
61   //! The decorations to display on the window.
62   /*!
63     This is by default the same value as in the Client::decorations, but it
64     is duplicated here so that it can be overridden per-window by the user.
65   */
66   Client::DecorationFlags _decorations;
67
68 public:
69   //! Constructs an Frame object, and reparents the client to itself
70   /*!
71     @param client The client window which will be decorated by the new Frame
72     @param style The style to use to decorate the frame
73   */
74   Frame(Client *client, otk::Style *style);
75   //! Destroys the Frame object
76   virtual ~Frame();
77
78   otk::Rect area() const {
79     otk::Rect a(_client->area());
80     a.setRect(a.x() - _size.left, a.y() - _size.top,
81               a.width() + _size.left + _size.right,
82               a.height() + _size.top + _size.bottom);
83     return a;
84   }
85   
86   //! Set the style to decorate the frame with
87   virtual void setStyle(otk::Style *style);
88
89   //! Empty overridden method to prevent automatic alignment of children
90   virtual void adjust();
91   
92   //! Displays focused decorations
93   virtual void focus();
94   //! Displays unfocused decorations
95   virtual void unfocus();
96
97   void setTitle(const otk::ustring &text);
98  
99   //! Reparents the client window from the root window onto the frame
100   void grabClient();
101   //! Reparents the client window back to the root window
102   void releaseClient();
103
104   //! Update the frame's size to match the client
105   void adjustSize();
106   //! Update the frame's position to match the client
107   void adjustPosition();
108   //! Shape the frame window to the client window
109   void adjustShape();
110
111   //! Applies gravity to the client's position to find where the frame should
112   //! be positioned.
113   /*!
114     @return The proper coordinates for the frame, based on the client.
115   */
116   void clientGravity(int &x, int &y);
117
118   //! Reversly applies gravity to the frame's position to find where the client
119   //! should be positioned.
120   /*!
121     @return The proper coordinates for the client, based on the frame.
122   */
123   void frameGravity(int &x, int &y);
124
125   //! Gets the window id of the frame's "plate" subelement
126   inline Window plate() const { return _plate.window(); }
127   //! Gets the window id of the frame's "titlebar" subelement
128   inline Window titlebar() const { return _titlebar.window(); }
129   //! Gets the window id of the frame's "label" subelement
130   inline Window label() const { return _label.window(); }
131   //! Gets the window id of the frame's "close button" subelement
132   inline Window button_close() const { return _button_close.window(); }
133   //! Gets the window id of the frame's "iconify button" subelement
134   inline Window button_iconify() const { return _button_iconify.window(); }
135   //! Gets the window id of the frame's "maximize button" subelement
136   inline Window button_max() const { return _button_max.window(); }
137   //! Gets the window id of the frame's "sticky button" subelement
138   inline Window button_stick() const { return _button_stick.window(); }
139   //! Gets the window id of the frame's "handle" subelement
140   inline Window handle() const { return _handle.window(); }
141   //! Gets the window id of the frame's "left grip" subelement
142   inline Window grip_left() const { return _grip_left.window(); }
143   //! Gets the window id of the frame's "right grip" subelement
144   inline Window grip_right() const { return _grip_right.window(); }
145
146 };
147
148 }
149
150 #endif // __frame_hh