1 // Screen.hh for Fluxbox Window Manager
2 // Copyright (c) 2001 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3 //
4 // Screen.hh for Blackbox - an X11 Window manager
5 // Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
24 
25 #ifndef SCREEN_HH
26 #define SCREEN_HH
27 
28 #include "FbWinFrame.hh"
29 #include "FbRootWindow.hh"
30 #include "RootTheme.hh"
31 #include "WinButtonTheme.hh"
32 #include "FbWinFrameTheme.hh"
33 #include "TooltipWindow.hh"
34 #include "ScreenResource.hh"
35 
36 #include "FbTk/MenuTheme.hh"
37 #include "FbTk/EventHandler.hh"
38 #include "FbTk/Resource.hh"
39 #include "FbTk/MultLayers.hh"
40 #include "FbTk/NotCopyable.hh"
41 #include "FbTk/Signal.hh"
42 #include "FbTk/RelCalcHelper.hh"
43 
44 #include "FocusControl.hh"
45 
46 #include <cstdio>
47 #include <list>
48 #include <vector>
49 #include <fstream>
50 #include <memory>
51 #include <map>
52 
53 class ClientPattern;
54 class FbMenu;
55 class Focusable;
56 class FluxboxWindow;
57 class WinClient;
58 class Workspace;
59 class Strut;
60 class Slit;
61 class Toolbar;
62 class HeadArea;
63 class ScreenPlacement;
64 class TooltipWindow;
65 class OSDWindow;
66 
67 namespace FbTk {
68 class Menu;
69 class ImageControl;
70 class LayerItem;
71 class FbWindow;
72 }
73 
74 
75 /// Handles screen connection, screen clients and workspaces
76 /**
77  Create workspaces, handles switching between workspaces and windows
78  */
79 class BScreen: public FbTk::EventHandler, private FbTk::NotCopyable {
80 public:
81     typedef std::list<FluxboxWindow *> Icons;
82     typedef std::vector<Workspace *> Workspaces;
83     typedef std::vector<std::string> WorkspaceNames;
84 
85     BScreen(FbTk::ResourceManager &rm,
86             const std::string &screenname, const std::string &altscreenname,
87             int scrn, int number_of_layers, unsigned int opts);
88     ~BScreen();
89 
90     void initWindows();
91     void initMenus();
92 
isRootColormapInstalled() const93     bool isRootColormapInstalled() const { return root_colormap_installed; }
isScreenManaged() const94     bool isScreenManaged() const { return m_state.managed; }
isWorkspaceWarping() const95     bool isWorkspaceWarping() const { return (m_workspaces_list.size() > 1) && *resource.workspace_warping; }
doAutoRaise() const96     bool doAutoRaise() const { return *resource.auto_raise; }
clickRaises() const97     bool clickRaises() const { return *resource.click_raises; }
doOpaqueMove() const98     bool doOpaqueMove() const { return *resource.opaque_move; }
doFullMax() const99     bool doFullMax() const { return *resource.full_max; }
getMaxIgnoreIncrement() const100     bool getMaxIgnoreIncrement() const { return *resource.max_ignore_inc; }
getMaxDisableMove() const101     bool getMaxDisableMove() const { return *resource.max_disable_move; }
getMaxDisableResize() const102     bool getMaxDisableResize() const { return *resource.max_disable_resize; }
doShowWindowPos() const103     bool doShowWindowPos() const { return *resource.show_window_pos; }
defaultDeco() const104     const std::string &defaultDeco() const { return *resource.default_deco; }
105     const std::string windowMenuFilename() const;
imageControl()106     FbTk::ImageControl &imageControl() { return *m_image_control.get(); }
107     // menus
rootMenu() const108     const FbMenu &rootMenu() const { return *m_rootmenu.get(); }
rootMenu()109     FbMenu &rootMenu() { return *m_rootmenu.get(); }
configMenu() const110     const FbMenu &configMenu() const { return *m_configmenu.get(); }
configMenu()111     FbMenu &configMenu() { return *m_configmenu.get(); }
windowMenu() const112     const FbMenu &windowMenu() const { return *m_windowmenu.get(); }
windowMenu()113     FbMenu &windowMenu() { return *m_windowmenu.get(); }
114 
getTabPlacement() const115     FbWinFrame::TabPlacement getTabPlacement() const { return *resource.tab_placement; }
116 
noFocusWhileTypingDelay() const117     unsigned int noFocusWhileTypingDelay() const { return *resource.typing_delay; }
allowRemoteActions() const118     const bool allowRemoteActions() const { return *resource.allow_remote_actions; }
clientMenuUsePixmap() const119     const bool clientMenuUsePixmap() const { return *resource.clientmenu_use_pixmap; }
getDefaultInternalTabs() const120     const bool getDefaultInternalTabs() const { return *resource.default_internal_tabs; }
getTabsUsePixmap() const121     const bool getTabsUsePixmap() const { return *resource.tabs_use_pixmap; }
getMaxOverTabs() const122     const bool getMaxOverTabs() const { return *resource.max_over_tabs; }
123 
getTabWidth() const124     unsigned int getTabWidth() const { return *resource.tab_width; }
125     /// @return the slit, @see Slit
slit()126     Slit *slit() { return m_slit.get(); }
127     /// @return the slit, @see Slit
slit() const128     const Slit *slit() const { return m_slit.get(); }
129     /**
130      * @param w the workspace number
131      * @return workspace for the given workspace number
132      */
getWorkspace(unsigned int w)133     Workspace *getWorkspace(unsigned int w) { return ( w < m_workspaces_list.size() ? m_workspaces_list[w] : 0); }
134     /**
135      * @param w the workspace number
136      * @return workspace for the given workspace number
137      */
getWorkspace(unsigned int w) const138     const Workspace *getWorkspace(unsigned int w) const {
139         return (w < m_workspaces_list.size() ? m_workspaces_list[w] : 0);
140     }
141     /// @return the current workspace
currentWorkspace()142     Workspace *currentWorkspace() { return m_current_workspace; }
currentWorkspace() const143     const Workspace *currentWorkspace() const { return m_current_workspace; }
144     /// @return the workspace menu
workspaceMenu() const145     const FbMenu &workspaceMenu() const { return *m_workspacemenu.get(); }
146     /// @return the workspace menu
workspaceMenu()147     FbMenu &workspaceMenu() { return *m_workspacemenu.get(); }
148     /// @return focus control handler
focusControl() const149     const FocusControl &focusControl() const { return *m_focus_control; }
150     /// @return focus control handler
focusControl()151     FocusControl &focusControl() { return *m_focus_control; }
152     /// @return the current workspace id
153     unsigned int currentWorkspaceID() const;
154     /**
155 
156      *
157     */
158     /// @return maximum screen bound to the left for a specific xinerama head
159     unsigned int maxLeft(int head) const;
160     /// @return maximum screen bound to the right for a specific xinerama head
161     unsigned int maxRight(int head) const;
162     /// @return maximum screen bound at the top for the specified xinerama head
163     unsigned int maxTop(int head) const;
164      /// @return maximum screen bound at bottom for the specified xinerama head
165     unsigned int maxBottom(int head) const;
166     /// @return true if window is kde dock app
167     bool isKdeDockapp(Window win) const;
168     /// @return true if dock app was added, else false
169     bool addKdeDockapp(Window win);
170     /// @return screen width, @see rootWindow()
width() const171     unsigned int width() const { return rootWindow().width(); }
172     /// @return screen height, @see rootWindow()
height() const173     unsigned int height() const { return rootWindow().height(); }
174     /// @return number of the screen, @see rootWindow()
screenNumber() const175     int screenNumber() const { return rootWindow().screenNumber(); }
176 
177     /// @return number of workspaces
numberOfWorkspaces() const178     size_t numberOfWorkspaces() const { return m_workspaces_list.size(); }
179 
iconList() const180     const Icons &iconList() const { return m_icon_list; }
iconList()181     Icons &iconList() { return m_icon_list; }
182 
getWorkspacesList() const183     const Workspaces &getWorkspacesList() const { return m_workspaces_list; }
getWorkspacesList()184     Workspaces &getWorkspacesList() { return m_workspaces_list; }
getWorkspaceNames() const185     const WorkspaceNames &getWorkspaceNames() const { return m_workspace_names; }
186     /**
187        @name Screen signals
188     */
189     //@{
190     typedef FbTk::Signal<BScreen&> ScreenSignal;
191     /// client list signal
clientListSig()192     ScreenSignal &clientListSig() { return m_clientlist_sig; }
193     /// icon list sig
iconListSig()194     ScreenSignal &iconListSig() { return m_iconlist_sig; }
195     /// workspace count signal
workspaceCountSig()196     ScreenSignal &workspaceCountSig() { return m_workspacecount_sig; }
197     /// workspace names signal
workspaceNamesSig()198     ScreenSignal &workspaceNamesSig() { return m_workspacenames_sig; }
199     /// workspace area signal
workspaceAreaSig()200     ScreenSignal &workspaceAreaSig() { return m_workspace_area_sig; }
201     /// current workspace signal
currentWorkspaceSig()202     ScreenSignal &currentWorkspaceSig() { return m_currentworkspace_sig; }
203     /// focused window signal
focusedWindowSig()204     FbTk::Signal<BScreen&, FluxboxWindow*, WinClient*> &focusedWindowSig() { return m_focusedwindow_sig; }
205     /// reconfigure signal
reconfigureSig()206     ScreenSignal &reconfigureSig() { return m_reconfigure_sig; }
resizeSig()207     ScreenSignal &resizeSig() { return m_resize_sig; }
bgChangeSig()208     ScreenSignal &bgChangeSig() { return m_bg_change_sig; }
209     //@}
210 
211     void propertyNotify(Atom atom);
212     void keyPressEvent(XKeyEvent &ke);
213     void keyReleaseEvent(XKeyEvent &ke);
214     void buttonPressEvent(XButtonEvent &be);
215 
216     /**
217      * Cycles focus of windows
218      * @param opts focus options
219      * @param pat specific pattern to match windows with
220      * @param reverse the order of cycling
221      */
222     void cycleFocus(int opts = 0, const ClientPattern *pat = 0, bool reverse = false);
223 
isCycling() const224     bool isCycling() const { return m_state.cycling; }
225 
226     /**
227      * For extras to add menus.
228      * These menus will be marked internal,
229      * and deleted when the window dies (as opposed to Screen
230      */
231     void addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu);
232 
getEdgeSnapThreshold() const233     int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
234 
setRootColormapInstalled(bool r)235     void setRootColormapInstalled(bool r) { root_colormap_installed = r;  }
236 
saveTabPlacement(FbWinFrame::TabPlacement place)237     void saveTabPlacement(FbWinFrame::TabPlacement place) { *resource.tab_placement = place; }
238 
saveWorkspaces(int w)239     void saveWorkspaces(int w) { *resource.workspaces = w;  }
240 
focusedWinFrameTheme()241     FbTk::ThemeProxy<FbWinFrameTheme> &focusedWinFrameTheme() { return *m_focused_windowtheme.get(); }
focusedWinFrameTheme() const242     const FbTk::ThemeProxy<FbWinFrameTheme> &focusedWinFrameTheme() const { return *m_focused_windowtheme.get(); }
unfocusedWinFrameTheme()243     FbTk::ThemeProxy<FbWinFrameTheme> &unfocusedWinFrameTheme() { return *m_unfocused_windowtheme.get(); }
unfocusedWinFrameTheme() const244     const FbTk::ThemeProxy<FbWinFrameTheme> &unfocusedWinFrameTheme() const { return *m_unfocused_windowtheme.get(); }
245 
menuTheme()246     FbTk::ThemeProxy<FbTk::MenuTheme> &menuTheme() { return *m_menutheme.get(); }
menuTheme() const247     const FbTk::ThemeProxy<FbTk::MenuTheme> &menuTheme() const { return *m_menutheme.get(); }
rootTheme() const248     const FbTk::ThemeProxy<RootTheme> &rootTheme() const { return *m_root_theme.get(); }
249 
focusedWinButtonTheme()250     FbTk::ThemeProxy<WinButtonTheme> &focusedWinButtonTheme() { return *m_focused_winbutton_theme.get(); }
focusedWinButtonTheme() const251     const FbTk::ThemeProxy<WinButtonTheme> &focusedWinButtonTheme() const { return *m_focused_winbutton_theme.get(); }
unfocusedWinButtonTheme()252     FbTk::ThemeProxy<WinButtonTheme> &unfocusedWinButtonTheme() { return *m_unfocused_winbutton_theme.get(); }
unfocusedWinButtonTheme() const253     const FbTk::ThemeProxy<WinButtonTheme> &unfocusedWinButtonTheme() const { return *m_unfocused_winbutton_theme.get(); }
pressedWinButtonTheme()254     FbTk::ThemeProxy<WinButtonTheme> &pressedWinButtonTheme() { return *m_pressed_winbutton_theme.get(); }
pressedWinButtonTheme() const255     const FbTk::ThemeProxy<WinButtonTheme> &pressedWinButtonTheme() const { return *m_pressed_winbutton_theme.get(); }
256 
rootWindow()257     FbRootWindow &rootWindow() { return m_root_window; }
rootWindow() const258     const FbRootWindow &rootWindow() const { return m_root_window; }
259 
dummyWindow()260     FbTk::FbWindow &dummyWindow() { return m_dummy_window; }
dummyWindow() const261     const FbTk::FbWindow &dummyWindow() const { return m_dummy_window; }
262 
layerManager()263     FbTk::MultLayers &layerManager() { return m_layermanager; }
layerManager() const264     const FbTk::MultLayers &layerManager() const { return m_layermanager; }
resourceManager()265     FbTk::ResourceManager &resourceManager() { return m_resource_manager; }
resourceManager() const266     const FbTk::ResourceManager &resourceManager() const { return m_resource_manager; }
name() const267     const std::string &name() const { return m_name; }
altName() const268     const std::string &altName() const { return m_altname; }
isShuttingdown() const269     bool isShuttingdown() const { return m_state.shutdown; }
270     bool isRestart();
271 
placementStrategy()272     ScreenPlacement &placementStrategy() { return *m_placement_strategy; }
placementStrategy() const273     const ScreenPlacement &placementStrategy() const { return *m_placement_strategy; }
274 
275     int addWorkspace();
276     int removeLastWorkspace();
277     // scroll workspaces
278     /**
279      * Jump forward to a workspace
280      * @param delta number of steps to jump
281      */
282     void nextWorkspace(int delta = 1);
283     /**
284      * Jump backwards to a workspace
285      * @param delta number of steps to jump
286      */
287     void prevWorkspace(int delta = 1);
288     /**
289      * Jump right to a workspace.
290      * @param delta number of steps to jump
291      */
292     void rightWorkspace(int delta);
293     /**
294      * Jump left to a workspace
295      * @param delta number of steps to jump
296      */
297     void leftWorkspace(int delta);
298 
299     /// update workspace name for given workspace
300     void updateWorkspaceName(unsigned int w);
301     /// remove all workspace names
302     void removeWorkspaceNames();
303     /// add a workspace name to the end of the workspace name list
304     void addWorkspaceName(const char *name);
305     /// add a window to the icon list
306     void addIcon(FluxboxWindow *win);
307     /// remove a window from the icon list
308     void removeIcon(FluxboxWindow *win);
309     /// remove a window
310     void removeWindow(FluxboxWindow *win);
311     /// remove a client
312     void removeClient(WinClient &client);
313     /**
314      * Gets name of a specific workspace
315      * @param workspace the workspace number to get the name of
316      * @return name of the workspace
317      */
318     std::string getNameOfWorkspace(unsigned int workspace) const;
319     /// changes workspace to specified id
320     void changeWorkspaceID(unsigned int, bool revert = true);
321     /**
322      * Sends a window to a workspace
323      * @param workspace the workspace id
324      * @param win the window to send
325      * @param changeworkspace whether current workspace should change
326      */
327     void sendToWorkspace(unsigned int workspace, FluxboxWindow *win=0,
328                          bool changeworkspace=true);
329     /**
330      * Reassociate a window to another workspace
331      * @param window the window to reassociate
332      * @param workspace_id id of the workspace
333      * @param ignore_sticky ignores any sticky windows
334      */
335     void reassociateWindow(FluxboxWindow *window, unsigned int workspace_id,
336                            bool ignore_sticky);
337 
338 
339     void reconfigure();
340     void reconfigureTabs();
341     void rereadMenu();
342     void rereadWindowMenu();
343     void shutdown();
344     /// show position window centered on the screen with "X x Y" text
345     void showPosition(int x, int y);
346     void hidePosition();
347     /// show geomentry with "width x height"-text, not size of window
348     void showGeometry(unsigned int width, unsigned int height);
349     void hideGeometry();
350 
351     /// @param text the text to be displayed in the tooltip window
352     void showTooltip(const FbTk::BiDiString &text);
353     /// Hides the tooltip window
354     void hideTooltip();
355 
tooltipWindow()356     TooltipWindow& tooltipWindow() { return *m_tooltip_window; }
357 
358     void setLayer(FbTk::LayerItem &item, int layernum);
359     // remove? no, items are never removed from their layer until they die
360 
361     /// updates root window size and resizes/reconfigures screen clients
362     /// that depends on screen size (slit)
363     /// (and maximized windows?)
364     void updateSize();
365 
366     // Xinerama-related functions
367 
368     /// @return true if xinerama is available
hasXinerama() const369     bool hasXinerama() const { return m_xinerama.avail; }
370     /// @return umber of xinerama heads
numHeads() const371     int numHeads() const { return m_xinerama.heads.size(); }
372 
373     void initXinerama();
374     void clearXinerama();
375     void clearHeads();
376     /// clean up xinerama
377 
378     /**
379      * Determines head number for a position
380      * @param x position in pixels on the screen
381      * @param y position in pixels on the screen
382      * @return head number at this position
383      */
384     int getHead(int x, int y) const;
385     /// @return head number of window
386     int getHead(const FbTk::FbWindow &win) const;
387     /// @return the current head number
388     int getCurrHead() const;
389     /// @return head x position
390     int getHeadX(int head) const;
391     /// @return head y position
392     int getHeadY(int head) const;
393     /// @return width of the head
394     int getHeadWidth(int head) const;
395     /// @return height of the head
396     int getHeadHeight(int head) const;
397 
398     ///  @return the new (x,y) for a rectangle fitted on a head
399     std::pair<int,int> clampToHead(int head, int x, int y, int w, int h) const;
400 
401     // magic to allow us to have "on head" placement (menu) without
402     // the object really knowing about it.
403     template <typename OnHeadObject>
404     int getOnHead(OnHeadObject &obj) const;
405 
406     // grouping - we want ordering, so we can either search for a
407     // group to the left, or to the right (they'll be different if
408     // they exist).
409     WinClient *findGroupLeft(WinClient &winclient);
410     WinClient *findGroupRight(WinClient &winclient);
411 
412     /// create window frame for client window and attach it
413     FluxboxWindow *createWindow(Window clientwin);
414     /// creates a window frame for a winclient. The client is attached to the window
415     FluxboxWindow *createWindow(WinClient &client);
416     /// request workspace space, i.e "don't maximize over this area"
417     Strut *requestStrut(int head, int left, int right, int top, int bottom);
418     /// remove requested space and destroy strut
419     void clearStrut(Strut *strut);
420     /// updates max avaible area for the workspace
421     void updateAvailableWorkspaceArea();
422 
423     // for extras to add menus. These menus must be marked
424     // internal for their safety, and __the extension__ must
425     // delete and remove the menu itself (opposite to Window)
426     void addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu);
427     void removeConfigMenu(FbTk::Menu &menu);
428 
429 
430     /// Adds a resource to managed resource list
431     /// This resource is now owned by Screen and will be destroyed
432     /// when screen dies
433     void addManagedResource(FbTk::Resource_base *resource);
434 
435     int calRelativeSize(int head, int i, char type);
436     int calRelativeWidth(int head, int i);
437     int calRelativeHeight(int head, int i);
438 
439     int calRelativePosition(int head, int i, char type);
440     int calRelativePositionWidth(int head, int i);
441     int calRelativePositionHeight(int head, int i);
442 
443     int calRelativeDimension(int head, int i, char type);
444     int calRelativeDimensionWidth(int head, int i);
445     int calRelativeDimensionHeight(int head, int i);
446 
447 private:
448     void setupConfigmenu(FbTk::Menu &menu);
449     void renderGeomWindow();
450     void renderPosWindow();
451     void focusedWinFrameThemeReconfigured();
452 
453     int getGap(int head, const char type);
454     float getXGap(int head);
455     float getYGap(int head);
456 
457     const Strut* availableWorkspaceArea(int head) const;
458 
459     FbTk::SignalTracker m_tracker;
460     ScreenSignal m_reconfigure_sig; ///< reconfigure signal
461 
462     FbTk::Signal<BScreen&, FluxboxWindow*, WinClient*> m_focusedwindow_sig;  ///< focused window signal
463     ScreenSignal m_resize_sig; ///< resize signal
464     ScreenSignal m_workspace_area_sig; ///< workspace area changed signal
465     ScreenSignal m_iconlist_sig; ///< notify if a window gets iconified/deiconified
466     ScreenSignal m_clientlist_sig;  ///< client signal
467     ScreenSignal m_bg_change_sig; ///< background change signal
468     ScreenSignal m_workspacecount_sig; ///< workspace count signal
469     ScreenSignal m_currentworkspace_sig; ///< current workspace signal
470     ScreenSignal m_workspacenames_sig; ///< workspace names signal
471 
472     FbTk::MultLayers m_layermanager;
473 
474     bool root_colormap_installed;
475 
476     std::auto_ptr<FbTk::ImageControl> m_image_control;
477     std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
478 
479     Icons m_icon_list;
480 
481     std::auto_ptr<Slit>     m_slit;
482     std::auto_ptr<Toolbar>  m_toolbar;
483 
484     Workspace *m_current_workspace;
485 
486     WorkspaceNames m_workspace_names;
487     Workspaces m_workspaces_list;
488 
489     std::auto_ptr<FbWinFrameTheme> m_focused_windowtheme,
490                                    m_unfocused_windowtheme;
491     std::auto_ptr<WinButtonTheme> m_focused_winbutton_theme,
492             m_unfocused_winbutton_theme, m_pressed_winbutton_theme;
493     std::auto_ptr<FbTk::MenuTheme> m_menutheme;
494     std::auto_ptr<RootTheme> m_root_theme;
495 
496     FbRootWindow m_root_window;
497     std::auto_ptr<OSDWindow> m_geom_window;
498     std::auto_ptr<OSDWindow> m_pos_window;
499     std::auto_ptr<TooltipWindow> m_tooltip_window;
500     FbTk::FbWindow m_dummy_window;
501 
502     ScreenResource resource;
503 
504     /// Holds manage resources that screen destroys
505     FbTk::ResourceManager::ResourceList m_managed_resources;
506 
507     FbTk::ResourceManager &m_resource_manager;
508     const std::string m_name, m_altname;
509 
510     FocusControl *m_focus_control;
511     ScreenPlacement *m_placement_strategy;
512 
513     // This is a map of windows to clients for clients that had a left
514     // window set, but that window wasn't present at the time
515     typedef std::map<Window, WinClient *> Groupables;
516     Groupables m_expecting_groups;
517 
518     const ClientPattern *m_cycle_opts;
519 
520     // Xinerama related private data
521     struct XineramaHeadInfo {
522         int _x, _y, _width, _height;
xBScreen::XineramaHeadInfo523         int x() const { return _x; }
yBScreen::XineramaHeadInfo524         int y() const { return _y; }
widthBScreen::XineramaHeadInfo525         int width() const { return _width; }
heightBScreen::XineramaHeadInfo526         int height() const { return _height; }
527     };
528     struct {
529         bool avail;
530         int center_x;
531         int center_y;
532         std::vector<XineramaHeadInfo> heads;
533     } m_xinerama;
534 
535     std::vector<HeadArea*> m_head_areas;
536 
537     struct {
538         bool cycling;
539         bool restart;
540         bool shutdown;
541         bool managed;
542     } m_state;
543     unsigned int m_opts; // hold Fluxbox::OPT_SLIT etc
544 };
545 
546 
547 #endif // SCREEN_HH
548