]> icculus.org git repositories - mikachu/openbox.git/blob - src/screen.hh
add support for desktop layouts specified by pagers
[mikachu/openbox.git] / src / screen.hh
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 #ifndef   __screen_hh
3 #define   __screen_hh
4
5 /*! @file screen.hh
6   @brief Screen manages a single screen
7 */
8
9 extern "C" {
10 #include <X11/Xlib.h>
11 }
12
13 #include "otk/strut.hh"
14 #include "otk/rect.hh"
15 #include "otk/screeninfo.hh"
16 #include "otk/eventhandler.hh"
17 #include "otk/property.hh"
18 #include "otk/ustring.hh"
19
20 #include <string>
21 #include <list>
22
23 namespace ob {
24
25 class Client;
26
27 struct DesktopLayout {
28   enum Corner { TopLeft, TopRight, BottomRight, BottomLeft };
29   enum Direction { Horizontal, Vertical };
30
31   Direction orientation;
32   Corner start_corner;
33   unsigned int rows;
34   unsigned int columns;
35 };
36
37 //! Manages a single screen
38 /*!
39 */
40 class Screen : public otk::EventHandler {
41 public:
42   //! Holds a list of otk::Strut objects
43   typedef std::vector<otk::Strut> StrutList;
44   //! Holds a list of otk::Rect objects
45   typedef std::vector<otk::Rect> RectList;
46
47   static const unsigned long event_mask = ColormapChangeMask |
48                                           EnterWindowMask |
49                                           LeaveWindowMask |
50                                           PropertyChangeMask |
51                                           SubstructureNotifyMask |
52                                           SubstructureRedirectMask |
53                                           ButtonPressMask |
54                                           ButtonReleaseMask;
55
56   //! Holds a list of Clients
57   typedef std::list<Client*> ClientList;
58   //! All managed clients on the screen (in order of being mapped)
59   ClientList clients;
60   
61 private:
62   //! Was %Openbox able to manage the screen?
63   bool _managed;
64
65   //! The number of the screen on the X server
66   int _number;
67
68   //! Information about this screen
69   const otk::ScreenInfo *_info;
70   
71   //! Area usable for placement etc (total - struts), one per desktop,
72   //! plus one extra for windows on all desktops
73   RectList _area;
74
75   //! Combined strut from all of the clients' struts, one per desktop,
76   //! plus one extra for windows on all desktops
77   StrutList _struts;
78
79   //!  An offscreen window which gets focus when nothing else has it
80   Window _focuswindow;
81
82   //! An offscreen window which shows that a NETWM compliant window manager is
83   //! running
84   Window _supportwindow;
85
86   //! A list of all managed clients on the screen, in their stacking order
87   ClientList _stacking;
88
89   //! The desktop currently being displayed
90   unsigned int _desktop;
91
92   //! The number of desktops
93   unsigned int _num_desktops;
94
95   //! The names of all desktops
96   otk::Property::StringVect _desktop_names;
97
98   DesktopLayout _layout;
99
100   //! Calculate the Screen::_area member
101   void calcArea();
102   //! Set the list of supported NETWM atoms on the root window
103   void changeSupportedAtoms();
104   //! Set the client list on the root window
105   /*!
106     Sets the _NET_CLIENT_LIST root window property.<br>
107     Also calls Screen::updateStackingList.
108   */
109   void changeClientList();
110   //! Set the client stacking list on the root window
111   /*!
112     Set the _NET_CLIENT_LIST_STACKING root window property.
113   */
114   void changeStackingList();
115   //! Set the work area hint on the root window
116   /*!
117     Set the _NET_WORKAREA root window property.
118   */
119   void changeWorkArea();
120
121   //! Get desktop names from the root window property
122   void updateDesktopNames();
123
124   //! Gets the layout of the desktops from the root window property
125   void updateDesktopLayout();
126
127   //! Changes to the specified desktop, displaying windows on it and hiding
128   //! windows on the others.
129   /*!
130     @param desktop The number of the desktop to switch to (starts from 0).
131     If the desktop is out of valid range, it is ignored.
132   */
133   void changeDesktop(unsigned int desktop);
134
135   //! Changes the number of desktops.
136   /*!
137     @param num The number of desktops that should exist. This value must be
138                greater than 0 or it will be ignored.
139   */
140   void changeNumDesktops(unsigned int num);
141
142 public:
143 #ifndef SWIG
144   //! Constructs a new Screen object
145   Screen(int screen);
146   //! Destroys the Screen object
147   virtual ~Screen();
148 #endif
149
150   inline int number() const { return _number; }
151   
152   //! Returns if the screen was successfully managed
153   /*!
154     If this is false, then the screen should be deleted and should NOT be
155     used.
156   */
157   inline bool managed() const { return _managed; }
158   //!  An offscreen window which gets focus when nothing else has it
159   inline Window focuswindow() const { return _focuswindow; }
160   //! Returns the desktop being displayed
161   inline unsigned int desktop() const { return _desktop; }
162   //! Returns the number of desktops
163   inline unsigned int numDesktops() const { return _num_desktops; }
164
165   //! Returns the area of the screen not reserved by applications' Struts
166   /*!
167     @param desktop The desktop number of the area to retrieve for. A value of
168                    0xffffffff will return an area that combines all struts
169                    on all desktops.
170   */
171   const otk::Rect& area(unsigned int desktop) const;
172
173   const DesktopLayout& desktopLayout() const { return _layout; }
174
175   //! Update's the screen's combined strut of all the clients.
176   /*!
177     Clients should call this whenever they change their strut.
178   */
179   void updateStruts();
180
181   //! Manage any pre-existing windows on the screen
182   void manageExisting();
183   //! Manage a client window
184   /*!
185     This gives the window a frame, reparents it, selects events on it, etc.
186   */
187   void manageWindow(Window window);
188   //! Unmanage a client
189   /*!
190     This removes the window's frame, reparents it to root, unselects events on
191     it, etc.
192     @param client The client to unmanage
193   */
194   void unmanageWindow(Client *client);
195
196   //! Raises a client window above all others in its stacking layer
197   /*!
198     raiseWindow has a couple of constraints that lowerWindow does not.<br>
199     1) raiseWindow can be called after changing a Client's stack layer, and
200        the list will be reorganized properly.<br>
201     2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be
202        called for the specified client.
203   */
204   void raiseWindow(Client *client);
205
206   //! Lowers a client window below all others in its stacking layer
207   void lowerWindow(Client *client);
208
209   //! Sets the name of a desktop by changing the root window property
210   /*!
211     @param i The index of the desktop to set the name for (starts at 0)
212     @param name The name to set for the desktop
213     If the index is too large, it is simply ignored.
214   */
215   void setDesktopName(unsigned int i, const otk::ustring &name);
216
217   void installColormap(bool install) const;
218
219   virtual void propertyHandler(const XPropertyEvent &e);
220   virtual void clientMessageHandler(const XClientMessageEvent &e);
221   virtual void mapRequestHandler(const XMapRequestEvent &e);
222 };
223
224 }
225
226 #endif// __screen_hh