00001 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*- 00002 #ifndef __screen_hh 00003 #define __screen_hh 00004 00005 /*! @file screen.hh 00006 @brief Screen manages a single screen 00007 */ 00008 00009 extern "C" { 00010 #include <X11/Xlib.h> 00011 } 00012 00013 #include "widgetbase.hh" 00014 #include "otk/renderstyle.hh" 00015 #include "otk/strut.hh" 00016 #include "otk/rect.hh" 00017 #include "otk/screeninfo.hh" 00018 #include "otk/eventhandler.hh" 00019 #include "otk/property.hh" 00020 #include "otk/ustring.hh" 00021 00022 #include <string> 00023 #include <list> 00024 00025 namespace ob { 00026 00027 class Client; 00028 00029 //! Manages a single screen 00030 /*! 00031 */ 00032 class Screen : public otk::EventHandler, public WidgetBase { 00033 public: 00034 //! Holds a list of otk::Strut objects 00035 typedef std::list<otk::Strut*> StrutList; 00036 00037 static const unsigned long event_mask = ColormapChangeMask | 00038 EnterWindowMask | 00039 LeaveWindowMask | 00040 PropertyChangeMask | 00041 SubstructureNotifyMask | 00042 SubstructureRedirectMask | 00043 ButtonPressMask | 00044 ButtonReleaseMask; 00045 00046 //! Holds a list of Clients 00047 typedef std::list<Client*> ClientList; 00048 //! All managed clients on the screen (in order of being mapped) 00049 ClientList clients; 00050 00051 private: 00052 //! Was %Openbox able to manage the screen? 00053 bool _managed; 00054 00055 //! The number of the screen on the X server 00056 int _number; 00057 00058 //! Information about this screen 00059 const otk::ScreenInfo *_info; 00060 00061 //! The style with which to render on the screen 00062 otk::RenderStyle _style; 00063 00064 //! Is the root colormap currently installed? 00065 bool _root_cmap_installed; 00066 00067 //! Area usable for placement etc (total - struts) 00068 otk::Rect _area; 00069 00070 //! Combined strut from all of the clients' struts 00071 otk::Strut _strut; 00072 00073 //! An offscreen window which gets focus when nothing else has it 00074 Window _focuswindow; 00075 00076 //! An offscreen window which shows that a NETWM compliant window manager is 00077 //! running 00078 Window _supportwindow; 00079 00080 //! A list of all managed clients on the screen, in their stacking order 00081 ClientList _stacking; 00082 00083 //! The desktop currently being displayed 00084 long _desktop; 00085 00086 //! The number of desktops 00087 long _num_desktops; 00088 00089 //! The names of all desktops 00090 otk::Property::StringVect _desktop_names; 00091 00092 //! Calculate the Screen::_area member 00093 void calcArea(); 00094 //! Set the list of supported NETWM atoms on the root window 00095 void changeSupportedAtoms(); 00096 //! Set the client list on the root window 00097 /*! 00098 Sets the _NET_CLIENT_LIST root window property.<br> 00099 Also calls Screen::updateStackingList. 00100 */ 00101 void changeClientList(); 00102 //! Set the client stacking list on the root window 00103 /*! 00104 Set the _NET_CLIENT_LIST_STACKING root window property. 00105 */ 00106 void changeStackingList(); 00107 //! Set the work area hint on the root window 00108 /*! 00109 Set the _NET_WORKAREA root window property. 00110 */ 00111 void changeWorkArea(); 00112 00113 //! Get desktop names from the root window property 00114 void updateDesktopNames(); 00115 00116 //! Changes to the specified desktop, displaying windows on it and hiding 00117 //! windows on the others. 00118 /*! 00119 @param desktop The number of the desktop to switch to (starts from 0). 00120 If the desktop is out of valid range, it is ignored. 00121 */ 00122 void changeDesktop(long desktop); 00123 00124 //! Changes the number of desktops. 00125 /*! 00126 @param num The number of desktops that should exist. This value must be 00127 greater than 0 or it will be ignored. 00128 */ 00129 void changeNumDesktops(long num); 00130 00131 public: 00132 #ifndef SWIG 00133 //! Constructs a new Screen object 00134 Screen(int screen); 00135 //! Destroys the Screen object 00136 virtual ~Screen(); 00137 #endif 00138 00139 inline int number() const { return _number; } 00140 00141 //! Returns if the screen was successfully managed 00142 /*! 00143 If this is false, then the screen should be deleted and should NOT be 00144 used. 00145 */ 00146 inline bool managed() const { return _managed; } 00147 //! Returns the area of the screen not reserved by applications' Struts 00148 inline const otk::Rect &area() const { return _area; } 00149 //! Returns the style in use on the screen 00150 inline const otk::RenderStyle *style() const { return &_style; } 00151 //! An offscreen window which gets focus when nothing else has it 00152 inline Window focuswindow() const { return _focuswindow; } 00153 //! Returns the desktop being displayed 00154 inline long desktop() const { return _desktop; } 00155 //! Returns the number of desktops 00156 inline long numDesktops() const { return _num_desktops; } 00157 00158 //! Update's the screen's combined strut of all the clients. 00159 /*! 00160 Clients should call this whenever they change their strut. 00161 */ 00162 void updateStrut(); 00163 00164 //! Manage any pre-existing windows on the screen 00165 void manageExisting(); 00166 //! Manage a client window 00167 /*! 00168 This gives the window a frame, reparents it, selects events on it, etc. 00169 */ 00170 void manageWindow(Window window); 00171 //! Unmanage a client 00172 /*! 00173 This removes the window's frame, reparents it to root, unselects events on 00174 it, etc. 00175 @param client The client to unmanage 00176 */ 00177 void unmanageWindow(Client *client); 00178 00179 //! Raises a client window above all others in its stacking layer 00180 /*! 00181 raiseWindow has a couple of constraints that lowerWindow does not.<br> 00182 1) raiseWindow can be called after changing a Client's stack layer, and 00183 the list will be reorganized properly.<br> 00184 2) raiseWindow guarantees that XRestackWindows() will <i>always</i> be 00185 called for the specified client. 00186 */ 00187 void raiseWindow(Client *client); 00188 00189 //! Lowers a client window below all others in its stacking layer 00190 void lowerWindow(Client *client); 00191 00192 //! Sets the name of a desktop by changing the root window property 00193 /*! 00194 @param i The index of the desktop to set the name for (starts at 0) 00195 @param name The name to set for the desktop 00196 If the index is too large, it is simply ignored. 00197 */ 00198 void setDesktopName(long i, const otk::ustring &name); 00199 00200 void installColormap(bool install) const; 00201 00202 virtual void propertyHandler(const XPropertyEvent &e); 00203 virtual void clientMessageHandler(const XClientMessageEvent &e); 00204 virtual void mapRequestHandler(const XMapRequestEvent &e); 00205 }; 00206 00207 } 00208 00209 #endif// __screen_hh