69
70
#define DEBUG_EWMH 1
72
Atom NET_CURRENT_DESKTOP;
73
static Atom NET_ACTIVE_WINDOW;
74
static Atom NET_CLIENT_LIST;
75
static Atom NET_CLIENT_LIST_STACKING;
76
static Atom NET_DESKTOP_GEOMETRY;
77
static Atom NET_DESKTOP_VIEWPORT;
78
static Atom NET_NUMBER_OF_DESKTOPS;
79
static Atom NET_SHOWING_DESKTOP;
80
static Atom NET_SUPPORTED;
81
static Atom NET_SUPPORTING_WM_CHECK;
82
static Atom NET_VIRTUAL_ROOTS;
83
static Atom NET_WM_DESKTOP;
84
static Atom NET_WM_ICON;
85
static Atom NET_WM_MOVERESIZE;
86
static Atom NET_WM_NAME;
87
static Atom NET_WM_STATE;
88
static Atom NET_WM_STATE_MAXIMIZED_VERT;
89
static Atom NET_WM_STATE_MAXIMIZED_HORZ;
90
static Atom NET_WM_STATE_FULLSCREEN;
91
static Atom NET_WM_STRUT;
92
static Atom NET_WM_STRUT_PARTIAL;
93
static Atom NET_WM_WINDOW_TYPE;
94
static Atom NET_WM_WINDOW_TYPE_DESKTOP;
95
static Atom NET_WM_WINDOW_TYPE_DOCK;
96
static Atom NET_WM_WINDOW_TYPE_NORMAL;
97
static Atom NET_WORKAREA;
98
static Atom UTF8_STRING;
72
Atom XEWMHAtom[NUM_EWMH_XATOMS];
100
74
#define NET_WM_STATE_REMOVE 0 /* remove/unset property */
101
75
#define NET_WM_STATE_ADD 1 /* add/set property */
151
125
static void EwmhInitAtoms(void)
153
MANAGER = XInternAtom(dpy, "MANAGER", False);
154
NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
155
NET_CLIENT_LIST = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
156
NET_CLIENT_LIST_STACKING = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
157
NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
158
NET_DESKTOP_GEOMETRY = XInternAtom(dpy, "_NET_DESKTOP_GEOMETRY", False);
159
NET_DESKTOP_VIEWPORT = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False);
160
NET_NUMBER_OF_DESKTOPS = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
161
NET_SHOWING_DESKTOP = XInternAtom(dpy, "_NET_SHOWING_DESKTOP", False);
162
NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", False);
163
NET_SUPPORTING_WM_CHECK = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
164
NET_VIRTUAL_ROOTS = XInternAtom(dpy, "_NET_VIRTUAL_ROOTS", False);
165
NET_WM_DESKTOP = XInternAtom(dpy, "_NET_WM_DESKTOP", False);
166
NET_WM_ICON = XInternAtom(dpy, "_NET_WM_ICON", False);
167
NET_WM_MOVERESIZE = XInternAtom(dpy, "_NET_WM_MOVERESIZE", False);
168
NET_WM_NAME = XInternAtom(dpy, "_NET_WM_NAME", False);
169
NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False);
170
NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT",
172
NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ",
174
NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN",
176
NET_WM_STRUT = XInternAtom(dpy, "_NET_WM_STRUT", False);
177
NET_WM_STRUT_PARTIAL = XInternAtom(dpy, "_NET_WM_STRUT_PARTIAL", False);
178
NET_WM_WINDOW_TYPE = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
179
NET_WM_WINDOW_TYPE_DESKTOP = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DESKTOP",
181
NET_WM_WINDOW_TYPE_DOCK = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
182
NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_NORMAL",
184
NET_WORKAREA = XInternAtom(dpy, "_NET_WORKAREA", False);
185
UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False);
127
XInternAtoms(dpy, XEWMHAtomNames, NUM_EWMH_XATOMS, False, XEWMHAtom);
188
130
static int caughtError;
335
277
GenerateTimestamp(scr);
337
279
SendPropertyMessage(scr->XineramaRoot, scr->XineramaRoot,
338
MANAGER, lastTimestamp, wmAtom, scr->icccm_Window, 0, 0,
280
XA_MANAGER, lastTimestamp, wmAtom, scr->icccm_Window, 0, 0,
339
281
StructureNotifyMask);
405
347
/* Set _NET_SUPPORTING_WM_CHECK on root window */
406
348
data[0] = scr->icccm_Window;
407
349
XChangeProperty(dpy, scr->XineramaRoot,
408
NET_SUPPORTING_WM_CHECK, XA_WINDOW,
350
XA__NET_SUPPORTING_WM_CHECK, XA_WINDOW,
409
351
32, PropModeReplace,
410
352
(unsigned char *)data, 1);
414
356
* this also belongs with _NET_SUPPORTING_WM_CHECK
416
358
XChangeProperty(dpy, scr->icccm_Window,
417
NET_WM_NAME, UTF8_STRING,
359
XA__NET_WM_NAME, XA_UTF8_STRING,
418
360
8, PropModeReplace,
419
361
(unsigned char *)"ctwm", 4);
421
363
data[0] = scr->icccm_Window;
422
364
XChangeProperty(dpy, scr->icccm_Window,
423
NET_SUPPORTING_WM_CHECK, XA_WINDOW,
365
XA__NET_SUPPORTING_WM_CHECK, XA_WINDOW,
424
366
32, PropModeReplace,
425
367
(unsigned char *)data, 1);
432
374
XChangeProperty(dpy, scr->XineramaRoot,
433
NET_DESKTOP_VIEWPORT, XA_CARDINAL,
375
XA__NET_DESKTOP_VIEWPORT, XA_CARDINAL,
434
376
32, PropModeReplace,
435
377
(unsigned char *)data, 2);
437
379
data[0] = scr->rootw;
438
380
data[1] = scr->rooth;
439
381
XChangeProperty(dpy, scr->XineramaRoot,
440
NET_DESKTOP_GEOMETRY, XA_CARDINAL,
382
XA__NET_DESKTOP_GEOMETRY, XA_CARDINAL,
441
383
32, PropModeReplace,
442
384
(unsigned char *)data, 2);
473
415
long supported[30];
476
supported[i++] = NET_SUPPORTING_WM_CHECK;
477
supported[i++] = NET_DESKTOP_VIEWPORT;
478
supported[i++] = NET_NUMBER_OF_DESKTOPS;
479
supported[i++] = NET_CURRENT_DESKTOP;
480
supported[i++] = NET_DESKTOP_GEOMETRY;
481
supported[i++] = NET_WM_ICON;
482
supported[i++] = NET_WM_DESKTOP;
483
supported[i++] = NET_CLIENT_LIST;
484
supported[i++] = NET_CLIENT_LIST_STACKING;
485
supported[i++] = NET_WM_WINDOW_TYPE;
486
supported[i++] = NET_WM_WINDOW_TYPE_NORMAL;
487
supported[i++] = NET_WM_WINDOW_TYPE_DESKTOP;
488
supported[i++] = NET_WM_WINDOW_TYPE_DOCK;
489
supported[i++] = NET_WM_STRUT;
490
supported[i++] = NET_WM_STRUT_PARTIAL;
491
supported[i++] = NET_SHOWING_DESKTOP;
492
supported[i++] = NET_WM_STATE;
493
supported[i++] = NET_WM_STATE_MAXIMIZED_VERT;
494
supported[i++] = NET_WM_STATE_MAXIMIZED_HORZ;
495
supported[i++] = NET_WM_STATE_FULLSCREEN;
496
supported[i++] = NET_ACTIVE_WINDOW;
497
supported[i++] = NET_WORKAREA;
498
supported[i++] = NET_WM_MOVERESIZE;
418
supported[i++] = XA__NET_SUPPORTING_WM_CHECK;
419
supported[i++] = XA__NET_DESKTOP_VIEWPORT;
420
supported[i++] = XA__NET_NUMBER_OF_DESKTOPS;
421
supported[i++] = XA__NET_CURRENT_DESKTOP;
422
supported[i++] = XA__NET_DESKTOP_GEOMETRY;
423
supported[i++] = XA__NET_WM_ICON;
424
supported[i++] = XA__NET_WM_DESKTOP;
425
supported[i++] = XA__NET_CLIENT_LIST;
426
supported[i++] = XA__NET_CLIENT_LIST_STACKING;
427
supported[i++] = XA__NET_WM_WINDOW_TYPE;
428
supported[i++] = XA__NET_WM_WINDOW_TYPE_NORMAL;
429
supported[i++] = XA__NET_WM_WINDOW_TYPE_DESKTOP;
430
supported[i++] = XA__NET_WM_WINDOW_TYPE_DOCK;
431
supported[i++] = XA__NET_WM_STRUT;
432
supported[i++] = XA__NET_WM_STRUT_PARTIAL;
433
supported[i++] = XA__NET_SHOWING_DESKTOP;
434
supported[i++] = XA__NET_WM_STATE;
435
supported[i++] = XA__NET_WM_STATE_MAXIMIZED_VERT;
436
supported[i++] = XA__NET_WM_STATE_MAXIMIZED_HORZ;
437
supported[i++] = XA__NET_WM_STATE_FULLSCREEN;
438
supported[i++] = XA__NET_ACTIVE_WINDOW;
439
supported[i++] = XA__NET_WORKAREA;
440
supported[i++] = XA__NET_WM_MOVERESIZE;
500
442
XChangeProperty(dpy, scr->XineramaRoot,
501
NET_SUPPORTED, XA_ATOM,
443
XA__NET_SUPPORTED, XA_ATOM,
502
444
32, PropModeReplace,
503
445
(unsigned char *)supported, i);
611
553
/* Messages regarding any window */
612
if(msg->message_type == NET_WM_DESKTOP) {
554
if(msg->message_type == XA__NET_WM_DESKTOP) {
613
555
EwmhClientMessage_NET_WM_DESKTOP(msg);
616
else if(msg->message_type == NET_WM_STATE) {
558
else if(msg->message_type == XA__NET_WM_STATE) {
617
559
EwmhClientMessage_NET_WM_STATE(msg);
620
else if(msg->message_type == NET_ACTIVE_WINDOW) {
562
else if(msg->message_type == XA__NET_ACTIVE_WINDOW) {
621
563
EwmhClientMessage_NET_ACTIVE_WINDOW(msg);
624
else if(msg->message_type == NET_WM_MOVERESIZE) {
566
else if(msg->message_type == XA__NET_WM_MOVERESIZE) {
625
567
EwmhClientMessage_NET_WM_MOVERESIZE(msg);
690
632
int area, width, height;
692
634
fetch_offset = 0;
693
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_ICON,
635
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_ICON,
694
636
fetch_offset, 8 * 1024, False, XA_CARDINAL,
695
637
&actual_type, &actual_format, &nitems,
696
638
&bytes_after, (unsigned char **)&prop) != Success || nitems == 0) {
772
714
/* we can fetch some more... */
774
716
fetch_offset += i + size;
775
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_ICON,
717
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_ICON,
776
718
fetch_offset, 8 * 1024, False, XA_CARDINAL,
777
719
&actual_type, &actual_format, &nitems,
778
720
&bytes_after, (unsigned char **)&prop) != Success) {
848
790
#ifdef DEBUG_EWMH
849
791
fprintf(stderr, "refetching from %d\n", fetch_offset);
850
792
#endif /* DEBUG_EWMH */
851
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_ICON,
793
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_ICON,
852
794
fetch_offset, 2 + area, False, XA_CARDINAL,
853
795
&actual_type, &actual_format, &nitems,
854
796
&bytes_after, (unsigned char **)&prop) != Success) {
1068
1010
static int atomToFlag(Atom a)
1070
if(a == NET_WM_STATE_MAXIMIZED_VERT) {
1012
if(a == XA__NET_WM_STATE_MAXIMIZED_VERT) {
1071
1013
return EWMH_STATE_MAXIMIZED_VERT;
1073
if(a == NET_WM_STATE_MAXIMIZED_HORZ) {
1015
if(a == XA__NET_WM_STATE_MAXIMIZED_HORZ) {
1074
1016
return EWMH_STATE_MAXIMIZED_HORZ;
1076
if(a == NET_WM_STATE_FULLSCREEN) {
1018
if(a == XA__NET_WM_STATE_FULLSCREEN) {
1077
1019
return EWMH_STATE_FULLSCREEN;
1311
1253
int EwmhHandlePropertyNotify(XPropertyEvent *event, TwmWindow *twm_win)
1313
if(event->atom == NET_WM_ICON) {
1255
if(event->atom == XA__NET_WM_ICON) {
1314
1256
EwmhHandle_NET_WM_ICONNotify(event, twm_win);
1317
else if(event->atom == NET_WM_STRUT_PARTIAL ||
1318
event->atom == NET_WM_STRUT) {
1259
else if(event->atom == XA__NET_WM_STRUT_PARTIAL ||
1260
event->atom == XA__NET_WM_STRUT) {
1319
1261
EwmhHandle_NET_WM_STRUTNotify(event, twm_win);
1431
1373
unsigned long *prop;
1432
1374
int occupation;
1434
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_DESKTOP,
1376
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_DESKTOP,
1435
1377
0, MAXWORKSPACE, False, XA_CARDINAL,
1436
1378
&actual_type, &actual_format, &nitems,
1437
1379
&bytes_after, (unsigned char **)&prop) != Success) {
1548
1490
fprintf(stderr, "Unable to allocate memory for EWMH client list.\n");
1551
XChangeProperty(dpy, Scr->Root, NET_CLIENT_LIST, XA_WINDOW, 32,
1493
XChangeProperty(dpy, Scr->Root, XA__NET_CLIENT_LIST, XA_WINDOW, 32,
1552
1494
PropModeReplace, (unsigned char *)Scr->ewmh_CLIENT_LIST,
1553
1495
Scr->ewmh_CLIENT_LIST_used);
1587
1529
/* If window was not found, there is no need to update the property. */
1589
XChangeProperty(dpy, Scr->Root, NET_CLIENT_LIST, XA_WINDOW, 32,
1531
XChangeProperty(dpy, Scr->Root, XA__NET_CLIENT_LIST, XA_WINDOW, 32,
1590
1532
PropModeReplace, (unsigned char *)Scr->ewmh_CLIENT_LIST,
1591
1533
Scr->ewmh_CLIENT_LIST_used);
1633
1575
i, Scr->ewmh_CLIENT_LIST_used);
1636
XChangeProperty(dpy, Scr->Root, NET_CLIENT_LIST_STACKING, XA_WINDOW, 32,
1578
XChangeProperty(dpy, Scr->Root, XA__NET_CLIENT_LIST_STACKING, XA_WINDOW, 32,
1637
1579
PropModeReplace, (unsigned char *)prop, i);
1662
1604
twm_win->ewmhFlags = 0;
1664
Atom type = EwmhGetWindowProperty(twm_win->w, NET_WM_WINDOW_TYPE, XA_ATOM);
1606
Atom type = EwmhGetWindowProperty(twm_win->w, XA__NET_WM_WINDOW_TYPE, XA_ATOM);
1666
if(type == NET_WM_WINDOW_TYPE_DESKTOP) {
1608
if(type == XA__NET_WM_WINDOW_TYPE_DESKTOP) {
1667
1609
twm_win->ewmhWindowType = wt_Desktop;
1669
else if(type == NET_WM_WINDOW_TYPE_DOCK) {
1611
else if(type == XA__NET_WM_WINDOW_TYPE_DOCK) {
1670
1612
twm_win->ewmhWindowType = wt_Dock;
1774
1716
unsigned long *prop;
1775
1717
EwmhStrut *strut;
1777
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_STRUT_PARTIAL,
1719
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_STRUT_PARTIAL,
1778
1720
0, 4, False, XA_CARDINAL,
1779
1721
&actual_type, &actual_format, &nitems,
1780
1722
&bytes_after, (unsigned char **)&prop) != Success) {
1781
if(XGetWindowProperty(dpy, twm_win->w, NET_WM_STRUT,
1723
if(XGetWindowProperty(dpy, twm_win->w, XA__NET_WM_STRUT,
1782
1724
0, 4, False, XA_CARDINAL,
1783
1725
&actual_type, &actual_format, &nitems,
1784
1726
&bytes_after, (unsigned char **)&prop) != Success) {
1959
1902
if(flags & EWMH_STATE_MAXIMIZED_VERT) {
1960
prop[i++] = NET_WM_STATE_MAXIMIZED_VERT;
1903
prop[i++] = XA__NET_WM_STATE_MAXIMIZED_VERT;
1962
1905
if(flags & EWMH_STATE_MAXIMIZED_HORZ) {
1963
prop[i++] = NET_WM_STATE_MAXIMIZED_HORZ;
1906
prop[i++] = XA__NET_WM_STATE_MAXIMIZED_HORZ;
1965
1908
if(flags & EWMH_STATE_FULLSCREEN) {
1966
prop[i++] = NET_WM_STATE_FULLSCREEN;
1909
prop[i++] = XA__NET_WM_STATE_FULLSCREEN;
1969
XChangeProperty(dpy, Scr->XineramaRoot, NET_WM_STATE, XA_CARDINAL, 32,
1912
XChangeProperty(dpy, Scr->XineramaRoot, XA__NET_WM_STATE, XA_CARDINAL, 32,
1970
1913
PropModeReplace, (unsigned char *)prop, i);
1982
1925
/* w */ prop[2] = scr->rootw - scr->BorderLeft - scr->BorderRight;
1983
1926
/* h */ prop[3] = scr->rooth - scr->BorderTop - scr->BorderBottom;
1985
XChangeProperty(dpy, Scr->XineramaRoot, NET_WORKAREA, XA_CARDINAL, 32,
1928
XChangeProperty(dpy, Scr->XineramaRoot, XA__NET_WORKAREA, XA_CARDINAL, 32,
1986
1929
PropModeReplace, (unsigned char *)prop, 4);