32
28
#define MWM_HINTS_STATUS (1L << 3)
33
29
/* Number of CARD32 entries in MWM hints data structure */
34
30
#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
35
/* List of all EWMH atoms supoorted by WM */
36
Atom *ewmh_list = NULL;
37
/* Length of previously-mentioned list */
38
unsigned long ewmh_list_len = 0;
39
/* Atom: _NET_SUPPORTED */
40
Atom xa_net_supported = None;
42
/* Check if WM supports EWMH */
43
int ewmh_check_support(Display *dpy)
50
/* Check for presence of _NET_SUPPORTED atom */
51
if (xa_net_supported == None)
52
xa_net_supported = XInternAtom(dpy, "_NET_SUPPORTED", True);
53
if (xa_net_supported == None) return FAILURE;
55
/* Retrive the value of _NET_SUPPORTED property of root window */
56
if (!x11_get_win_prop32(dpy, DefaultRootWindow(dpy), xa_net_supported, XA_ATOM, (unsigned char **) &ewmh_list, &ewmh_list_len)) {
57
xa_net_supported = None;
62
for (i = 0; i < ewmh_list_len; i++) {
63
atom_name = XGetAtomName(dpy, ewmh_list[i]);
64
DBG(8, ("_NET_WM_SUPPORTED[%d] = 0x%x (%s)\n", i, ewmh_list[i], atom_name));
73
/* Check if atom is in the list of supported EWMH atoms */
74
int ewmh_atom_supported(Atom atom)
77
if (atom == None || xa_net_supported == None) return False;
78
for (i = 0; i < ewmh_list_len; i++)
79
if (atom == ewmh_list[i])
32
/* Check if WM that supports EWMH hints is present on given display */
33
int ewmh_wm_present(Display *dpy)
35
Window *check_win, *check_win_self_ref;
36
unsigned long cw_len = 0, cwsr_len = 0;
38
/* see _NET_SUPPORTING_WM_CHECK in the WM spec. */
39
rc = x11_get_root_winlist_prop(dpy,
40
XInternAtom(dpy, _NET_SUPPORTING_WM_CHECK, False),
41
(unsigned char **) &check_win,
43
if (x11_ok() && rc && cw_len == 1) {
44
LOG_TRACE(("_NET_SUPPORTING_WM_CHECK (root) = 0x%x\n", check_win[0]));
45
x11_get_window_prop32(dpy,
47
XInternAtom(dpy, _NET_SUPPORTING_WM_CHECK, False),
49
(unsigned char **) &check_win_self_ref,
51
rc = (x11_ok() && rc && cwsr_len == 1 && check_win[0] == check_win_self_ref[0]);
52
LOG_TRACE(("_NET_SUPPORTING_WM_CHECK (self reference) = 0x%x\n", check_win[0]));
54
if (cw_len != 0) XFree(check_win);
55
if (cwsr_len != 0) XFree(check_win_self_ref);
56
LOG_TRACE(("EWMH WM %sdetected\n", rc ? "" : "not "));
84
60
/* Add EWMH window state for the given window */
89
65
XWindowAttributes xwa;
92
/* Check if WM supports EWMH window states */
93
prop = XInternAtom(dpy, "_NET_WM_STATE", True);
94
atom = XInternAtom(dpy, state, True);
95
if (atom == None || prop == None || !ewmh_atom_supported(atom)) return FAILURE;
97
DBG(8, ("adding window state %s (0x%x)\n", state, atom));
67
prop = XInternAtom(dpy, "_NET_WM_STATE", False);
68
atom = XInternAtom(dpy, state, False);
69
LOG_TRACE(("adding state %s to window 0x%x\n", state, atom));
70
/* Ping the window and get its state */
99
71
rc = XGetWindowAttributes(dpy, wnd, &xwa);
100
72
if (!x11_ok() || !rc ) return FAILURE;
102
if (xwa.map_state != IsUnmapped) {
103
/* For unmapped windows, ask WM to add the window state */
104
return x11_send_client_msg32(dpy, DefaultRootWindow(dpy), wnd, prop,
74
if (xwa.map_state != IsUnmapped && ewmh_wm_present(dpy)) {
75
/* For mapped windows, ask WM (if it is here) to add the window state */
76
rc = x11_send_client_msg32(dpy, xwa.root, wnd, prop,
105
77
_NET_WM_STATE_ADD, atom, 0, 0, 0);
107
/* Else, add the window state ourselves */
108
XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
79
/* Else, alter the window state atom value ourselves */
80
rc = XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
113
86
/* Add EWMH window type for the given window */
118
/* Check if WM supports supports _NET_WM_WINDOW_TYPE and requested window type */
119
prop = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", True);
120
atom = XInternAtom(dpy, type, True);
121
if (atom == None || prop == None || !ewmh_atom_supported(atom)) return FAILURE;
91
prop = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
92
atom = XInternAtom(dpy, type, False);
93
LOG_TRACE(("adding type %s to window 0x%x\n", type, atom));
123
94
/* Update property value (append) */
124
95
XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
127
DBG(0, ("could append atom to the _NET_WM_WINDOW_TYPE list property of 0x%x\n", wnd));
135
/* List EWMH states that are set for the given window */
136
int ewmh_dump_window_states(Display *dpy, Window wnd)
139
unsigned long prop_len;
143
/* Check if WM supports _NET_WM_STATE */
144
prop = XInternAtom(tray_data.dpy, "_NET_WM_STATE", True);
145
if (prop == None) return FAILURE;
147
/* Retrive the list of states */
148
if (x11_get_win_prop32(dpy, wnd, prop, XA_ATOM, (unsigned char**) &data, &prop_len)) {
149
for (j = 0; j < prop_len; j++) {
150
tmp = XGetAtomName(tray_data.dpy, data[j]);
151
if (x11_ok() && tmp != NULL) {
152
DBG(8, ("0x%x:_NET_WM_STATE[%d] = %s\n", wnd, j, tmp));
99
/* Set data for _NET_WM_STRUT{,_PARTIAL} hints */
100
int ewmh_set_window_strut(Display *dpy, Window wnd, wm_strut_t wm_strut)
103
Atom prop_strut_partial;
104
prop_strut = XInternAtom(dpy, _NET_WM_STRUT, False);
105
prop_strut_partial = XInternAtom(dpy, _NET_WM_STRUT_PARTIAL, False);
106
XChangeProperty(dpy, wnd, prop_strut, XA_CARDINAL, 32, PropModeReplace,
107
(unsigned char *)wm_strut, _NET_WM_STRUT_SZ);
108
XChangeProperty(dpy, wnd, prop_strut_partial, XA_CARDINAL, 32, PropModeReplace,
109
(unsigned char *)wm_strut, _NET_WM_STRUT_PARTIAL_SZ);
113
/* Set CARD32 value of EWMH atom for a given window */
114
int ewmh_set_window_atom32(Display *dpy, Window wnd, char *prop_name, CARD32 value)
118
XWindowAttributes xwa;
120
prop = XInternAtom(dpy, prop_name, False);
121
LOG_TRACE(("0x%x: setting atom %s to 0x%x\n", wnd, prop_name, value));
122
/* Ping the window and get its state */
123
rc = XGetWindowAttributes(dpy, wnd, &xwa);
124
if (!x11_ok() || !rc ) return FAILURE;
125
if (xwa.map_state != IsUnmapped && ewmh_wm_present(dpy)) {
126
/* For mapped windows, ask WM (if it is here) to add the window state */
127
return x11_send_client_msg32(dpy, DefaultRootWindow(dpy), wnd, prop,
128
value, 2 /* source indication */, 0, 0, 0);
130
/* Else, alter the window state atom value ourselves */
131
XChangeProperty(dpy, wnd, prop, XA_ATOM, 32, PropModeAppend, (unsigned char *)&atom, 1);
163
136
/* Set MWM hints */
164
137
int mwm_set_hints(Display *dpy, Window wnd, unsigned long decorations, unsigned long functions)
168
141
unsigned long nitems, bytes_after;
169
142
static Atom atom = None, act_type;
171
143
/* Check if WM supports Motif WM hints */
172
144
if (atom == None) atom = XInternAtom(dpy, "_MOTIF_WM_HINTS", False);
173
145
if (atom == None) return FAILURE;
175
146
/* Get current hints */
176
147
rc = XGetWindowProperty(dpy, wnd, atom, 0, 5, False, atom,
177
148
&act_type, &act_fmt, &nitems, &bytes_after,
178
149
(unsigned char**) &prop);
180
150
if ((act_type == None && act_fmt == 0 && bytes_after == 0) || nitems == 0) {
181
151
/* Hints are either not set or have some other type.
182
152
* Reset all values. */
193
163
x11_ok(); /* Reset x11 error status */
197
166
/* Update value */
198
167
prop->flags |= MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
199
168
prop->decorations = decorations;
200
169
prop->functions = functions;
202
170
XChangeProperty(dpy, wnd, atom, atom, 32, PropModeReplace,
203
171
(unsigned char*) prop, PROP_MOTIF_WM_HINTS_ELEMENTS);
176
/* Dumps EWMH atoms supported by WM */
177
int ewmh_list_supported_atoms(Display *dpy)
180
unsigned long atom_list_len, i;
182
if (ewmh_wm_present(dpy)) {
183
if (x11_get_window_prop32(dpy,
184
DefaultRootWindow(dpy),
185
XInternAtom(dpy, _NET_SUPPORTED, False),
187
(unsigned char **) &atom_list,
190
for (i = 0; i < atom_list_len; i++) {
191
atom_name = XGetAtomName(dpy, atom_list[i]);
192
if (atom_name != NULL) {
193
LOG_TRACE(("_NET_SUPPORTED[%d]: %s (0x%x)\n", i, atom_name, atom_list[i]));
195
LOG_TRACE(("_NET_SUPPORTED[%d]: bogus value (0x%x)\n", i, atom_list[i]));
206
/* List EWMH states that are set for the given window */
207
int ewmh_dump_window_states(Display *dpy, Window wnd)
210
unsigned long prop_len;
213
/* Check if WM supports _NET_WM_STATE */
214
prop = XInternAtom(tray_data.dpy, "_NET_WM_STATE", True);
215
if (prop == None) return FAILURE;
216
/* Retrive the list of states */
217
if (x11_get_window_prop32(dpy, wnd, prop, XA_ATOM, (unsigned char**) &data, &prop_len)) {
218
for (j = 0; j < prop_len; j++) {
219
tmp = XGetAtomName(tray_data.dpy, data[j]);
220
if (x11_ok() && tmp != NULL) {
221
LOG_TRACE(("0x%x:_NET_WM_STATE[%d] = %s\n", wnd, j, tmp));