1 #ifndef __HERBSTLUFT_EWMH_H_
2 #define __HERBSTLUFT_EWMH_H_
3 
4 #include <X11/X.h>
5 #include <X11/Xlib.h>
6 #include <array>
7 #include <string>
8 #include <vector>
9 
10 /* actions on NetWmState */
11 #define _NET_WM_STATE_REMOVE        0    /* remove/unset property */
12 #define _NET_WM_STATE_ADD           1    /* add/set property */
13 #define _NET_WM_STATE_TOGGLE        2    /* toggle property  */
14 
15 enum {
16     NetSupported = 0,
17     NetClientList,
18     NetClientListStacking,
19     NetCloseWindow,
20     NetNumberOfDesktops,
21     NetCurrentDesktop,
22     NetDesktopNames,
23     NetWmDesktop,
24     NetDesktopViewport,
25     NetActiveWindow,
26     NetWmName,
27     NetSupportingWmCheck,
28     NetWmWindowType,
29     NetWmState,
30     NetWmWindowOpacity,
31     NetMoveresizeWindow,
32     NetWmMoveresize,
33     NetFrameExtents,
34     /* window states */
35     NetWmStateHidden,
36     NetWmStateFullscreen,
37     NetWmStateDemandsAttention,
38     /* window types */
39     NetWmWindowTypeDesktop,
40     NetWmWindowTypeFIRST = NetWmWindowTypeDesktop,
41     NetWmWindowTypeDock,
42     NetWmWindowTypeToolbar,
43     NetWmWindowTypeMenu,
44     NetWmWindowTypeUtility,
45     NetWmWindowTypeSplash,
46     NetWmWindowTypeDialog,
47     NetWmWindowTypeDropdownMenu,
48     NetWmWindowTypePopupMenu,
49     NetWmWindowTypeTooltip,
50     NetWmWindowTypeNotification,
51     NetWmWindowTypeCombo,
52     NetWmWindowTypeDnd,
53     NetWmWindowTypeNormal,
54     NetWmWindowTypeLAST = NetWmWindowTypeNormal,
55     /* the count of hints */
56     NetCOUNT
57 };
58 
59 // possible values for direction of a _NET_WM_MOVERESIZE client message
60 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
61 #define _NET_WM_MOVERESIZE_SIZE_TOP          1
62 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
63 #define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
64 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
65 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
66 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
67 #define _NET_WM_MOVERESIZE_SIZE_LEFT         7
68 #define _NET_WM_MOVERESIZE_MOVE              8   /* movement only */
69 #define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9   /* size via keyboard */
70 #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10   /* move via keyboard */
71 #define _NET_WM_MOVERESIZE_CANCEL           11   /* cancel operation */
72 
73 enum class WmState {
74     // see icccm:
75     // http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html#WM_STATE_Property
76     WSWithdrawnState = 0,
77     WSNormalState    = 1,
78     WSIconicState    = 3,
79 };
80 
81 class HSTag;
82 class Client;
83 class Root;
84 class TagManager;
85 class XConnection;
86 
87 class Ewmh {
88 public:
89     Ewmh(XConnection& xconnection);
90     ~Ewmh();
91 
92     //! initial EWMH state
93     class InitialState {
94     public:
95         size_t numberOfDesktops = 0;
96         std::vector<std::string> desktopNames;
97         //! client list before hlwm start
98         std::vector<Window> original_client_list_;
99         void print(FILE* file);
100     };
101 
102     enum class WM { Name, Protocols, Delete, State, ChangeState, TakeFocus, Last };
103 
104     void injectDependencies(Root* root);
105     void updateAll();
106 
107     void addClient(Window win);
108     void removeClient(Window win);
109     void updateWmName();
110 
111     void updateClientList();
112     const InitialState &initialState();
113     long windowGetInitialDesktop(Window win);
114     void updateClientListStacking();
115     void updateDesktops();
116     void updateDesktopNames();
117     void updateActiveWindow(Window win);
118     void updateCurrentDesktop();
119     void updateWindowState(Client* client);
120     void updateFrameExtents(Window win, int left, int right, int top, int bottom);
121     bool isWindowStateSet(Window win, Atom hint);
122     bool isFullscreenSet(Window win);
123     void clearClientProperties(Window win);
124     std::string getWindowTitle(Window win);
125 
126     int getWindowType(Window win);
127 
128     bool isOwnWindow(Window win);
129     void clearInputFocus();
130 
131     // set the desktop property of a window
132     void windowUpdateTag(Window win, HSTag* tag);
133 
134     void handleClientMessage(XClientMessageEvent* me);
135 
136     void setWindowOpacity(Window win, double opacity);
137 
138     void windowUpdateWmState(Window win, WmState state);
139 
140     static Ewmh& get(); // temporary singleton getter
141 
142     bool sendEvent(Window window, WM proto, bool checkProtocols);
143     void windowClose(Window window);
144 
X()145     XConnection& X() { return X_; }
146     Atom netatom(int netatomEnum);
147     const char* netatomName(int netatomEnum);
148 
149 private:
150     bool focusStealingAllowed(long source);
151     Root* root_ = nullptr;
152     TagManager* tags_ = nullptr;
153     XConnection& X_;
154     InitialState initialState_;
155     void readInitialEwmhState();
156     Atom wmatom(WM proto);
157     Atom wmatom_[(int)WM::Last] = {};
158 
159     //! array with Window-IDs in initial mapping order for _NET_CLIENT_LIST
160     std::vector<Window> netClientList_;
161     //! window that shows that the WM is still alive
162     Window      windowManagerWindow_;
163 
164     Atom netatom_[NetCOUNT] = {};
165     static const std::array<const char*,NetCOUNT> netatomNames_;
166 };
167 
168 #endif
169 
170