35#include <X11/extensions/shape.h>
37#include "ctwm_atoms.h"
39#include "ewmh_atoms.h"
43#include "functions_defs.h"
63#define NET_WM_STATE_REMOVE 0
64#define NET_WM_STATE_ADD 1
65#define NET_WM_STATE_TOGGLE 2
67#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
68#define _NET_WM_MOVERESIZE_SIZE_TOP 1
69#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
70#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
71#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
72#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
73#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
74#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
75#define _NET_WM_MOVERESIZE_MOVE 8
76#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
77#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
78#define _NET_WM_MOVERESIZE_CANCEL 11
96#define ALL_WORKSPACES 0xFFFFFFFFU
100 long l0,
long l1,
long l2,
long l3,
long l4,
105 e.xclient.type = ClientMessage;
106 e.xclient.message_type = messagetype;
107 e.xclient.display =
dpy;
108 e.xclient.window = about;
109 e.xclient.format = 32;
110 e.xclient.data.l[0] = l0;
111 e.xclient.data.l[1] = l1;
112 e.xclient.data.l[2] = l2;
113 e.xclient.data.l[3] = l3;
114 e.xclient.data.l[4] = l4;
116 XSendEvent(
dpy, to, False, mask, &e);
121 XInternAtoms(
dpy, XEWMHAtomNames, NUM_EWMH_XATOMS, False,
XEWMHAtom);
147 struct timespec tosleep;
153 tosleep.tv_nsec = (10 * 1000 * 1000);
159 XChangeProperty(
dpy, scr->icccm_Window,
160 XA_WM_CLASS, XA_STRING,
161 8, PropModeAppend, NULL, 0);
164 found = XCheckTypedWindowEvent(
dpy, scr->icccm_Window, PropertyNotify, &event);
168 nanosleep(&tosleep, NULL);
174 fprintf(stderr,
"GenerateTimestamp: time = %ld, timeout left = %d\n",
175 event.xproperty.time, timeout);
198 Window selectionOwner;
200 snprintf(atomname,
sizeof(atomname),
"WM_S%d", scr->
screen);
201 wmAtom = XInternAtom(
dpy, atomname, False);
203 selectionOwner = XGetSelectionOwner(
dpy, wmAtom);
204 if(selectionOwner == scr->icccm_Window) {
205 selectionOwner = None;
208 if(selectionOwner != None) {
209 XErrorHandler oldHandler;
218 XSelectInput(
dpy, selectionOwner, StructureNotifyMask);
221 XSetErrorHandler(oldHandler);
224 selectionOwner = None;
232 if(selectionOwner != None && !
CLarg.ewmh_replace) {
234 fprintf(stderr,
"A window manager is already running on screen %d\n",
241 XSetSelectionOwner(
dpy, wmAtom, scr->icccm_Window, CurrentTime);
243 if(XGetSelectionOwner(
dpy, wmAtom) != scr->icccm_Window) {
244 fprintf(stderr,
"Did not get window manager selection on screen %d\n",
254 if(selectionOwner != None) {
255 int timeout = 10 * 1000;
257 struct timespec tosleep;
261 tosleep.tv_nsec = (100 * 1000 * 1000);
265 int found = XCheckTypedWindowEvent(
dpy, selectionOwner, DestroyNotify, &event);
269 nanosleep(&tosleep, NULL);
274 fprintf(stderr,
"Timed out waiting for other window manager "
275 "on screen %d to quit\n",
293 XA_MANAGER,
EventTime, wmAtom, scr->icccm_Window, 0, 0,
294 StructureNotifyMask);
309 XSetWindowAttributes attrib;
312 fprintf(stderr,
"EwmhInitScreenEarly: XCreateWindow\n");
314 attrib.event_mask = PropertyChangeMask;
315 attrib.override_redirect = True;
318 CopyFromParent, InputOutput,
320 CWEventMask | CWOverrideRedirect,
323 XMapWindow(
dpy, scr->icccm_Window);
324 XLowerWindow(
dpy, scr->icccm_Window);
327 fprintf(stderr,
"EwmhInitScreenEarly: call EwmhReplaceWM\n");
330 XDestroyWindow(
dpy, scr->icccm_Window);
331 scr->icccm_Window = None;
334 fprintf(stderr,
"EwmhInitScreenEarly: return false\n");
340 fprintf(stderr,
"EwmhInitScreenEarly: return true\n");
354 data[0] = scr->icccm_Window;
356 XA__NET_SUPPORTING_WM_CHECK, XA_WINDOW,
358 (
unsigned char *)data, 1);
364 XChangeProperty(
dpy, scr->icccm_Window,
365 XA__NET_WM_NAME, XA_UTF8_STRING,
367 (
unsigned char *)
"ctwm", 4);
369 data[0] = scr->icccm_Window;
370 XChangeProperty(
dpy, scr->icccm_Window,
371 XA__NET_SUPPORTING_WM_CHECK, XA_WINDOW,
373 (
unsigned char *)data, 1);
381 XA__NET_DESKTOP_VIEWPORT, XA_CARDINAL,
383 (
unsigned char *)data, 2);
385 data[0] = scr->
rootw;
386 data[1] = scr->
rooth;
388 XA__NET_DESKTOP_GEOMETRY, XA_CARDINAL,
390 (
unsigned char *)data, 2);
402 XA__NET_NUMBER_OF_DESKTOPS, XA_CARDINAL,
404 (
unsigned char *)data, 1);
415 XA__NET_CURRENT_DESKTOP, XA_CARDINAL,
417 (
unsigned char *)data, 1);
424 supported[i++] = XA__NET_SUPPORTING_WM_CHECK;
425 supported[i++] = XA__NET_DESKTOP_VIEWPORT;
426 supported[i++] = XA__NET_NUMBER_OF_DESKTOPS;
427 supported[i++] = XA__NET_CURRENT_DESKTOP;
428 supported[i++] = XA__NET_DESKTOP_GEOMETRY;
429 supported[i++] = XA__NET_WM_ICON;
430 supported[i++] = XA__NET_WM_DESKTOP;
431 supported[i++] = XA__NET_CLIENT_LIST;
432 supported[i++] = XA__NET_CLIENT_LIST_STACKING;
433 supported[i++] = XA__NET_WM_WINDOW_TYPE;
434 supported[i++] = XA__NET_WM_WINDOW_TYPE_NORMAL;
435 supported[i++] = XA__NET_WM_WINDOW_TYPE_DESKTOP;
436 supported[i++] = XA__NET_WM_WINDOW_TYPE_DOCK;
437 supported[i++] = XA__NET_WM_STRUT;
438 supported[i++] = XA__NET_WM_STRUT_PARTIAL;
439 supported[i++] = XA__NET_SHOWING_DESKTOP;
440 supported[i++] = XA__NET_WM_STATE;
441 supported[i++] = XA__NET_WM_STATE_MAXIMIZED_VERT;
442 supported[i++] = XA__NET_WM_STATE_MAXIMIZED_HORZ;
443 supported[i++] = XA__NET_WM_STATE_FULLSCREEN;
444 supported[i++] = XA__NET_ACTIVE_WINDOW;
445 supported[i++] = XA__NET_WORKAREA;
446 supported[i++] = XA__NET_WM_MOVERESIZE;
447 supported[i++] = XA__NET_WM_STATE_SHADED;
448 supported[i++] = XA__NET_WM_STATE_ABOVE;
449 supported[i++] = XA__NET_WM_STATE_BELOW;
450 supported[i++] = XA__NET_CLOSE_WINDOW;
453 XA__NET_SUPPORTED, XA_ATOM,
455 (
unsigned char *)supported, i);
477 int numVscreens = scr->numVscreens;
479 if(numVscreens > 1) {
485 data = calloc(numVscreens,
sizeof(
long));
488 vs != NULL && i < numVscreens;
489 vs = vs->
next, i++) {
494 XA__NET_VIRTUAL_ROOTS, XA_WINDOW,
496 (
unsigned char *)data, numVscreens);
502 d0 = XA__NET_VIRTUAL_ROOTS;
504 XA__NET_SUPPORTED, XA_ATOM,
506 (
unsigned char *)&d0, 1);
533 for(scrnum = 0; scrnum <
NumScreens; scrnum++) {
549 fprintf(stderr,
"sev->window = %x\n", (
unsigned)sev->window);
563 if(msg->format != 32) {
568 if(msg->message_type == XA__NET_WM_DESKTOP) {
572 else if(msg->message_type == XA__NET_WM_STATE) {
576 else if(msg->message_type == XA__NET_ACTIVE_WINDOW) {
580 else if(msg->message_type == XA__NET_WM_MOVERESIZE) {
584 else if(msg->message_type == XA__NET_CLOSE_WINDOW) {
590 if(msg->window !=
Scr->XineramaRoot &&
591 msg->window !=
Scr->Root) {
593 fprintf(stderr,
"Received unrecognized client message: %s\n",
594 XGetAtomName(
dpy, msg->message_type));
599 if(msg->message_type == XA__NET_CURRENT_DESKTOP) {
603 else if(msg->message_type == XA__NET_SHOWING_DESKTOP) {
609 fprintf(stderr,
"Received unrecognized client message about root window: %s\n",
610 XGetAtomName(
dpy, msg->message_type));
642 unsigned long nitems, bytes_after;
648 int smaller_offset, larger_offset;
654 if(XGetWindowProperty(
dpy, twm_win->
w, XA__NET_WM_ICON,
655 fetch_offset, 8 * 1024, False, XA_CARDINAL,
656 &actual_type, &actual_format, &nitems,
657 &bytes_after, (
unsigned char **)&prop) != Success || nitems == 0) {
661 if(actual_format != 32) {
667 fprintf(stderr,
"_NET_WM_ICON data fetched\n");
676 wanted_area =
Scr->PreferredIconWidth *
Scr->PreferredIconHeight;
690 const int area = w * h;
693 fprintf(stderr,
"[%d+%d] w=%d h=%d\n", fetch_offset, offset, w, h);
697 if(area == wanted_area) {
699 fprintf(stderr,
"exact match [%d+%d=%d] w=%d h=%d\n", fetch_offset, offset,
700 fetch_offset + offset, w, h);
702 smaller_offset = fetch_offset + offset;
707 else if(area < wanted_area) {
710 fprintf(stderr,
"increase smaller, was [%d]\n", smaller_offset);
713 smaller_offset = fetch_offset + offset;
719 fprintf(stderr,
"decrease larger, was [%d]\n", larger_offset);
722 larger_offset = fetch_offset + offset;
726 if(i + size + 2 > nitems) {
728 fprintf(stderr,
"not enough data: %d + %d > %ld \n", i, size, nitems);
731 if(i + size + 2 <= nitems + bytes_after / 4) {
734 fetch_offset += i + size;
735 if(XGetWindowProperty(
dpy, twm_win->
w, XA__NET_WM_ICON,
736 fetch_offset, 8 * 1024, False, XA_CARDINAL,
737 &actual_type, &actual_format, &nitems,
738 &bytes_after, (
unsigned char **)&prop) != Success) {
755 if(smaller_offset >= 0) {
756 if(larger_offset >= 0) {
759 fprintf(stderr,
"choose nearest %d %d\n", smaller, larger);
761 if((
double)larger / wanted_area > (
double)wanted_area / smaller) {
762 offset = smaller_offset;
766 offset = larger_offset;
773 fprintf(stderr,
"choose smaller (only) %d\n", smaller);
775 offset = smaller_offset;
779 else if(larger_offset >= 0) {
782 fprintf(stderr,
"choose larger (only) %d\n", larger);
784 offset = larger_offset;
790 fprintf(stderr,
"nothing to choose from\n");
801 fprintf(stderr,
"offset = %d fetch_offset = %d\n", offset, fetch_offset);
802 fprintf(stderr,
"offset + 2 + area = %d fetch_offset + nitems = %ld\n",
803 offset + 2 + area, fetch_offset + nitems);
805 if(offset < fetch_offset ||
806 offset + 2 + area > fetch_offset + nitems) {
808 fetch_offset = offset;
810 fprintf(stderr,
"refetching from %d\n", fetch_offset);
812 if(XGetWindowProperty(
dpy, twm_win->
w, XA__NET_WM_ICON,
813 fetch_offset, 2 + area, False, XA_CARDINAL,
814 &actual_type, &actual_format, &nitems,
815 &bytes_after, (
unsigned char **)&prop) != Success) {
820 i = offset - fetch_offset;
824 fprintf(stderr,
"Chosen [%d] w=%d h=%d area=%d\n", offset, width, height, area);
826 assert(width * height == area);
840 int r = (argb >> 16) & 0xFF;
841 int g = (argb >> 8) & 0xFF;
842 int b = (argb >> 0) & 0xFF;
843 buffer_16bpp [
y * w +
x] = ((r >> 3) << 11) + ((g >> 2) << 5) + (b >> 3);
855 void (*store_data)(
int w,
int x,
int y,
int argb);
856 int x,
y, transparency;
858 unsigned char *maskbits;
873 ximage = XCreateImage(
dpy, CopyFromParent, scr->
d_depth, ZPixmap, 0,
880 ximage = XCreateImage(
dpy, CopyFromParent, scr->
d_depth, ZPixmap, 0,
885 fprintf(stderr,
"Screen unsupported depth for 32-bit icon: %d\n", scr->
d_depth);
892 fprintf(stderr,
"cannot create image for icon\n");
899 rowbytes = (width + 7) / 8;
900 maskbits = calloc(height, rowbytes);
908 for(
y = 0;
y < height;
y++) {
909 for(
x = 0;
x < width;
x++) {
910 unsigned long argb = prop[i++];
911 store_data(width,
x,
y, argb);
912 int opaque = ((argb >> 24) & 0xFF) >= 0x80;
914 maskbits [rowbytes *
y + (
x / 8)] |= 0x01 << (
x % 8);
923 pixret = XCreatePixmap(
dpy, scr->
Root, width, height, scr->
d_depth);
924 XPutImage(
dpy, pixret, gc, ximage, 0, 0, 0, 0, width, height);
925 XDestroyImage(ximage);
930 mask = XCreatePixmapFromBitmapData(
dpy, scr->
Root, (
char *)maskbits,
931 width, height, 1, 0, 1);
936 image->
width = width;
950 unsigned long valuemask;
951 XSetWindowAttributes attributes;
956 fprintf(stderr,
"EwmhHandlePropertyNotify: NET_WM_ICON\n");
964 fprintf(stderr,
"no icon, or not match_net_wm_icon\n");
983 valuemask = CWBackPixmap;
984 attributes.background_pixmap = image->
pixmap;
988 XCreateWindow(
dpy, twm_win->
icon->
w,
x, 0,
992 CopyFromParent,
Scr->d_visual,
993 valuemask, &attributes);
996 XShapeCombineMask(
dpy, twm_win->
icon->
bm_w, ShapeBounding, 0, 0, image->
mask,
998 XShapeCombineMask(
dpy, twm_win->
icon->
w, ShapeBounding,
x, 0, image->
mask,
1008 XShapeCombineRectangles(
dpy, twm_win->
icon->
w, ShapeBounding, 0,
1009 0, &rect, 1, ShapeUnion, 0);
1011 XMapSubwindows(
dpy, twm_win->
icon->
w);
1030# define CRWARN(x) fprintf(stderr, "atomToFlag: ignoring " #x "\n")
1032# define CRWARN(x) (void)0
1034#define CHKNRET(st) \
1035 if(a == XA__NET_WM_##st) { \
1036 if(LookInNameList(Scr->EWMHIgnore, #st)) { \
1044 CHKNRET(STATE_MAXIMIZED_VERT);
1045 CHKNRET(STATE_MAXIMIZED_HORZ);
1068 Window w = msg->window;
1070 int change, change1, change2, newValue;
1074 if(twm_win == NULL) {
1084 if(change1 == 0 && change2 != 0) {
1088 change = change1 | change2;
1090 switch(msg->data.l[0]) {
1093 printf(
"NET_WM_STATE_REMOVE: ");
1099 printf(
"NET_WM_STATE_ADD: ");
1105 printf(
"NET_WM_STATE_TOGGLE: ");
1107 newValue = ~twm_win->ewmhFlags & change;
1111 printf(
"invalid operation in NET_WM_STATE: %ld\n", msg->data.l[0]);
1116 printf(
"%s and %s\n", XGetAtomName(
dpy, msg->data.l[1]),
1117 XGetAtomName(
dpy, msg->data.l[2]));
1126 (newValue == 0 || newValue == change)) {
1155 newZoom = twm_win->
zoomed;
1161 newZoom = F_HORIZOOM;
1164 newZoom = F_FULLZOOM;
1167 newZoom = F_FULLSCREENZOOM;
1174 printf(
"EWMH_STATE_SHADED: newValue: %d old: %d\n", newValue,
1180 printf(
"EWMH_STATE_SHADED: change it\n");
1191 unsigned omask = 0, oval = 0;
1195#define DOBIT(fld) do { \
1196 if(change & EWMH_STATE_##fld) { omask |= OTP_AFLAG_##fld; } \
1197 if(newValue & EWMH_STATE_##fld) { oval |= OTP_AFLAG_##fld; } \
1229 Window w = msg->window;
1234 if(twm_win == NULL) {
1250 if(
Scr->RaiseOnWarp) {
1275 if(twm_win == NULL) {
1283 switch(msg->data.l[2]) {
1347 Window child = twm_win->
w;
1348 int x_root = twm_win->
frame_x;
1349 int y_root = twm_win->
frame_y;
1352 unsigned int dummy_mask;
1355 XQueryPointer(
dpy, twm_win->
frame, &
root, &child, &x_root, &y_root,
1356 &x_win, &y_win, &dummy_mask);
1359 xevent.type = ButtonPress;
1360 xevent.xbutton.root =
root;
1361 xevent.xbutton.window = child;
1362 xevent.xbutton.x_root = x_root;
1363 xevent.xbutton.y_root = y_root;
1364 xevent.xbutton.x = x_win;
1365 xevent.xbutton.y = y_win;
1393 if(tmp_win != NULL) {
1405 if(event->atom == XA__NET_WM_ICON) {
1409 else if(event->atom == XA__NET_WM_STRUT_PARTIAL ||
1410 event->atom == XA__NET_WM_STRUT) {
1414 else if(event->atom == XA__NET_WM_NAME) {
1418 twm_win->
names.net_wm_name = NULL;
1423 if(twm_win->
names.net_wm_name != NULL
1424 && strcmp(twm_win->
names.net_wm_name, prop) == 0) {
1432 twm_win->
names.net_wm_name = prop;
1438 else if(event->atom == XA__NET_WM_ICON_NAME) {
1442 twm_win->
names.net_wm_icon_name = NULL;
1447 if(twm_win->
names.net_wm_icon_name != NULL
1448 && strcmp(twm_win->
names.net_wm_icon_name, prop) == 0) {
1456 twm_win->
names.net_wm_icon_name = prop;
1492 if(!
Scr->workSpaceManagerActive) {
1493 workspaces[n++] = 0;
1514 workspaces[n++] = wsn;
1515 occupation &= ~(1 << wsn);
1521 if(occupation != 0) {
1526 if(occupation & mask) {
1527 workspaces[n++] = i;
1534 XChangeProperty(
dpy, twm_win->
w,
1535 XA__NET_WM_DESKTOP, XA_CARDINAL,
1536 32, PropModeReplace,
1537 (
unsigned char *)workspaces, n);
1545 unsigned long nitems, bytes_after;
1546 unsigned long *prop;
1547 unsigned long value;
1549 if(XGetWindowProperty(
dpy, w, name,
1551 &actual_type, &actual_format, &nitems,
1552 &bytes_after, (
unsigned char **)&prop) != Success) {
1556 if(actual_format == 32) {
1578 unsigned long *nitems_return)
1582 unsigned long bytes_after;
1583 unsigned long *prop;
1585 if(XGetWindowProperty(
dpy, w, name,
1586 0, 8192, False, type,
1587 &actual_type, &actual_format, nitems_return,
1588 &bytes_after, (
unsigned char **)&prop) != Success) {
1593 if(actual_format != 32) {
1604 unsigned long nitems;
1605 unsigned long *prop;
1611 XA__NET_WM_DESKTOP, XA_CARDINAL, &nitems);
1615 for(i = 0; i < nitems; i++) {
1616 unsigned int val = prop[i];
1620 else if(val < Scr->workSpaceMgr.count) {
1621 occupation |= 1 << val;
1624 occupation |= 1 << (
Scr->workSpaceMgr.count - 1);
1650 Window w = msg->window;
1658 if(twm_win == NULL) {
1665 if((vs = twm_win->
vs) != NULL) {
1669 val = (
unsigned int)msg->data.l[0];
1675 else if(val < Scr->workSpaceMgr.count) {
1676 occupation |= 1 << val;
1679 occupation |= 1 << (
Scr->workSpaceMgr.count - 1);
1691 XDeleteProperty(
dpy, twm_win->
w, XA__NET_WM_DESKTOP);
1703 if(
Scr->ewmh_CLIENT_LIST_size == 0) {
1709 Scr->ewmh_CLIENT_LIST_used++;
1710 if(
Scr->ewmh_CLIENT_LIST_used >
Scr->ewmh_CLIENT_LIST_size) {
1712 int tsz =
Scr->ewmh_CLIENT_LIST_size;
1714 Scr->ewmh_CLIENT_LIST_size *= 2;
1715 tp = realloc(
Scr->ewmh_CLIENT_LIST,
1716 sizeof(
long) *
Scr->ewmh_CLIENT_LIST_size);
1718 Scr->ewmh_CLIENT_LIST_size = tsz;
1719 fprintf(stderr,
"Unable to allocate memory for EWMH client list.\n");
1722 Scr->ewmh_CLIENT_LIST = tp;
1724 if(
Scr->ewmh_CLIENT_LIST) {
1725 Scr->ewmh_CLIENT_LIST[
Scr->ewmh_CLIENT_LIST_used - 1] = new_win->
w;
1728 Scr->ewmh_CLIENT_LIST_size = 0;
1729 fprintf(stderr,
"Unable to allocate memory for EWMH client list.\n");
1732 XChangeProperty(
dpy,
Scr->Root, XA__NET_CLIENT_LIST, XA_WINDOW, 32,
1733 PropModeReplace, (
unsigned char *)
Scr->ewmh_CLIENT_LIST,
1734 Scr->ewmh_CLIENT_LIST_used);
1749 if(
Scr->ewmh_CLIENT_LIST_size == 0) {
1752 for(i =
Scr->ewmh_CLIENT_LIST_used - 1; i >= 0; i--) {
1753 if(
Scr->ewmh_CLIENT_LIST[i] == old_win->
w) {
1754 memmove(&
Scr->ewmh_CLIENT_LIST[i],
1755 &
Scr->ewmh_CLIENT_LIST[i + 1],
1756 (
Scr->ewmh_CLIENT_LIST_used - 1 - i) *
sizeof(
Scr->ewmh_CLIENT_LIST[0]));
1757 Scr->ewmh_CLIENT_LIST_used--;
1758 if(
Scr->ewmh_CLIENT_LIST_used &&
1759 (
Scr->ewmh_CLIENT_LIST_used * 3) <
Scr->ewmh_CLIENT_LIST_size) {
1760 Scr->ewmh_CLIENT_LIST_size /= 2;
1761 Scr->ewmh_CLIENT_LIST = realloc(
Scr->ewmh_CLIENT_LIST,
1762 sizeof((
Scr->ewmh_CLIENT_LIST[0])) *
Scr->ewmh_CLIENT_LIST_size);
1770 XChangeProperty(
dpy,
Scr->Root, XA__NET_CLIENT_LIST, XA_WINDOW, 32,
1771 PropModeReplace, (
unsigned char *)
Scr->ewmh_CLIENT_LIST,
1772 Scr->ewmh_CLIENT_LIST_used);
1785 unsigned long *prop;
1790 size =
Scr->ewmh_CLIENT_LIST_used + 10;
1791 prop = calloc(size,
sizeof(
unsigned long));
1803 prop[i] = twm_win->
w;
1806 fprintf(stderr,
"Too many stacked windows\n");
1812 if(i !=
Scr->ewmh_CLIENT_LIST_used) {
1813 fprintf(stderr,
"Incorrect number of stacked windows: %d (expected %d)\n",
1814 i,
Scr->ewmh_CLIENT_LIST_used);
1817 XChangeProperty(
dpy,
Scr->Root, XA__NET_CLIENT_LIST_STACKING, XA_WINDOW, 32,
1818 PropModeReplace, (
unsigned char *)prop, i);
1825 unsigned long prop[1];
1829 XChangeProperty(
dpy,
Scr->Root, XA__NET_ACTIVE_WINDOW, XA_WINDOW, 32,
1830 PropModeReplace, (
unsigned char *)prop, 1);
1844 twm_win->ewmhFlags = 0;
1848 if(type == XA__NET_WM_WINDOW_TYPE_DESKTOP) {
1851 else if(type == XA__NET_WM_WINDOW_TYPE_DOCK) {
1852 twm_win->ewmhWindowType =
wt_Dock;
1866 switch(twm_win->ewmhWindowType) {
1878 switch(twm_win->ewmhWindowType) {
1889 switch(twm_win->ewmhWindowType) {
1900 switch(twm_win->ewmhWindowType) {
1923 while(strut != NULL) {
1924 left =
max(left, strut->
left);
1926 top =
max(top, strut->
top);
1929 strut = strut->
next;
1932 Scr->BorderLeft = left;
1933 Scr->BorderRight = right;
1934 Scr->BorderTop = top;
1935 Scr->BorderBottom = bottom;
1939 left, right, top, bottom);
1940 if(
Scr->BorderedLayout == NULL) {
1941 Scr->BorderedLayout =
Scr->Layout;
1959 unsigned long nitems;
1960 unsigned long *prop;
1964 XA__NET_WM_STRUT_PARTIAL, XA_CARDINAL,
1968 XA__NET_WM_STRUT, XA_CARDINAL, &nitems);
1978 printf(
"struts: prop = %p, nitems = %ld\n", prop, nitems);
1984 printf(
"struts: left %ld, right %ld, top %ld, bottom %ld\n",
1985 prop[0], prop[1], prop[2], prop[3]);
1994 if(
Scr->ewmhStruts == NULL &&
1998 Scr->BorderBottom) != 0) {
2007 strut->
left =
Scr->BorderLeft;
2009 strut->
top =
Scr->BorderTop;
2012 Scr->ewmhStruts = strut;
2024 strut =
Scr->ewmhStruts;
2026 while(strut != NULL) {
2027 if(strut->
win == twm_win) {
2030 strut = strut->
next;
2044 strut->
next =
Scr->ewmhStruts;
2045 Scr->ewmhStruts = strut;
2048 strut->
win = twm_win;
2049 strut->
left = prop[0];
2050 strut->
right = prop[1];
2051 strut->
top = prop[2];
2074 while(strut != NULL) {
2075 if(strut->
win == twm_win) {
2078 *prev = strut->
next;
2085 prev = &strut->
next;
2086 strut = strut->
next;
2109 XChangeProperty(
dpy, twm_win->
w,
2110 XA__NET_FRAME_EXTENTS, XA_CARDINAL,
2111 32, PropModeReplace,
2112 (
unsigned char *)data, 4);
2118 unsigned long prop[1];
2122 XChangeProperty(
dpy,
Scr->XineramaRoot, XA__NET_SHOWING_DESKTOP, XA_CARDINAL,
2124 PropModeReplace, (
unsigned char *)prop, 1);
2139 unsigned long prop[10];
2146 switch(twm_win->
zoomed) {
2161 case F_FULLSCREENZOOM:
2169 twm_win->ewmhFlags |= newFlags;
2206 flags = twm_win->ewmhFlags;
2210 prop[i++] = XA__NET_WM_STATE_MAXIMIZED_VERT;
2213 prop[i++] = XA__NET_WM_STATE_MAXIMIZED_HORZ;
2216 prop[i++] = XA__NET_WM_STATE_FULLSCREEN;
2219 prop[i++] = XA__NET_WM_STATE_SHADED;
2222 prop[i++] = XA__NET_WM_STATE_ABOVE;
2225 prop[i++] = XA__NET_WM_STATE_BELOW;
2228 XChangeProperty(
dpy, twm_win->
w, XA__NET_WM_STATE, XA_ATOM, 32,
2229 PropModeReplace, (
unsigned char *)prop, i);
2240 unsigned long *prop;
2241 unsigned long nitems;
2247 for(i = 0; i < nitems; i++) {
2262 unsigned long prop[4];
2269 XChangeProperty(
dpy,
Scr->XineramaRoot, XA__NET_WORKAREA, XA_CARDINAL, 32,
2270 PropModeReplace, (
unsigned char *)prop, 4);
#define ALLOW_DEAD_STORE(x)
int NumScreens
How many Screens are on our display.
ScreenInfo ** ScreenList
List of ScreenInfo structs for each Screen.
void DoShutdown(void)
Cleanup and exit ctwm.
void AutoRaiseWindow(TwmWindow *tmp)
static void EwmhRemoveStrut(TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_SIZE_TOP
void EwmhInitScreenLate(ScreenInfo *scr)
void EwmhUnmapNotify(TwmWindow *twm_win)
static Image * ExtractIcon(ScreenInfo *scr, unsigned long *prop, int width, int height)
static int EwmhGet_NET_WM_STATE(TwmWindow *twm_win)
int EwmhGetInitPriority(TwmWindow *twm_win)
static void EwmhSet_NET_WORKAREA(ScreenInfo *scr)
void EwmhSet_NET_WM_DESKTOP_ws(TwmWindow *twm_win, WorkSpace *ws)
void EwmhSet_NET_FRAME_EXTENTS(TwmWindow *twm_win)
Set _NET_FRAME_EXTENTS property.
static void convert_for_32(int w, int x, int y, int argb)
static void EwmhGetStrut(TwmWindow *twm_win, bool update)
bool EwmhClientMessage(XClientMessageEvent *msg)
static unsigned long * EwmhGetWindowProperties(Window w, Atom name, Atom type, unsigned long *nitems_return)
static void EwmhTerminateScreen(ScreenInfo *scr)
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT
Atom XEWMHAtom[NUM_EWMH_XATOMS]
static uint16_t * buffer_16bpp
static void EwmhClientMessage_NET_ACTIVE_WINDOW(XClientMessageEvent *msg)
static void EwmhClientMessage_NET_WM_DESKTOP(XClientMessageEvent *msg)
#define NET_WM_STATE_REMOVE
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
void EwmhSelectionClear(XSelectionClearEvent *sev)
int EwmhHandlePropertyNotify(XPropertyEvent *event, TwmWindow *twm_win)
void EwmhSet_NET_SHOWING_DESKTOP(int state)
#define _NET_WM_MOVERESIZE_SIZE_LEFT
static void EwmhClientMessage_NET_WM_STATE(XClientMessageEvent *msg)
static void EwmhClientMessage_NET_WM_MOVERESIZE(XClientMessageEvent *msg)
bool EwmhInitScreenEarly(ScreenInfo *scr)
void EwmhAddClientWindow(TwmWindow *new_win)
static int atomToFlag(Atom a)
bool EwmhHasBorder(TwmWindow *twm_win)
static void GenerateTimestamp(ScreenInfo *scr)
bool EwmhOnWindowRing(TwmWindow *twm_win)
static bool EwmhReplaceWM(ScreenInfo *scr)
static int CatchError(Display *display, XErrorEvent *event)
static void EwmhInitAtoms(void)
void EwmhSet_NET_WM_DESKTOP(TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_CANCEL
static void EwmhRecalculateStrut(void)
void EwmhDeleteClientWindow(TwmWindow *old_win)
void EwmhGetProperties(TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD
void EwmhSet_NET_ACTIVE_WINDOW(Window w)
static void EwmhHandle_NET_WM_STRUTNotify(XPropertyEvent *event, TwmWindow *twm_win)
static void SendPropertyMessage(Window to, Window about, Atom messagetype, long l0, long l1, long l2, long l3, long l4, long mask)
bool EwmhHasTitle(TwmWindow *twm_win)
static XEvent synth_btnevent_for_moveresize(TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD
static void EwmhClientMessage_NET_WM_STATEchange(TwmWindow *twm_win, int change, int newVal)
static void EwmhClientMessage_NET_CLOSE_WINDOW(XClientMessageEvent *msg)
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
static unsigned long EwmhGetWindowProperty(Window w, Atom name, Atom type)
#define NET_WM_STATE_TOGGLE
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM
void EwmhSet_NET_WM_STATE(TwmWindow *twm_win, int changes)
Image * EwmhGetIcon(ScreenInfo *scr, TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
void EwmhSet_NET_CLIENT_LIST_STACKING(void)
static uint32_t * buffer_32bpp
#define _NET_WM_MOVERESIZE_MOVE
static void EwmhHandle_NET_WM_ICONNotify(XPropertyEvent *event, TwmWindow *twm_win)
int EwmhGetOccupation(TwmWindow *twm_win)
#define _NET_WM_MOVERESIZE_SIZE_RIGHT
static void convert_for_16(int w, int x, int y, int argb)
#define EWMH_STATE_MAXIMIZED_VERT
#define EWMH_STATE_MAXIMIZED_HORZ
#define EWMH_STATE_SHADED
#define EWMH_STATE_FULLSCREEN
void ExecuteFunction(int func, void *action, Window w, TwmWindow *tmp_win, XEvent *eventp, int context, bool pulldown)
Window XineramaRoot
Root window holding our vscreens.
Window Root
Root window for the current vscreen.
VirtualScreen * vScreenList
Linked list of per-VS info.
int frame_x
X position on screen of frame.
int frame_y
Y position on screen of frame.
Window frame
The X window for the overall frame.
int frame_bw
2d border width.
unsigned int title_height
Height of the full title bar.
int frame_bw3D
3d border width.
void RedoIconName(TwmWindow *win)
int GetIconOffset(Icon *icon)
void FreeImage(Image *image)
void ChangeOccupation(TwmWindow *tmp_win, int newoccupation)
void OtpSetAflagMask(TwmWindow *twm_win, unsigned mask, unsigned setto)
int OtpEffectivePriority(TwmWindow *twm_win)
void OtpRestackWindow(TwmWindow *twm_win)
TwmWindow * OtpNextWinUp(TwmWindow *twm_win)
int OtpEffectiveDisplayPriority(TwmWindow *twm_win)
TwmWindow * OtpBottomWin(void)
RLayout * RLayoutCopyCropped(const RLayout *self, int left_margin, int right_margin, int top_margin, int bottom_margin)
Create a copy of an RLayout with given amounts cropped off the sides.
Info and control for each X Screen we control.
int BorderTop
BorderTop config var.
WorkSpaceMgr workSpaceMgr
Info about the WorkSpaceManager (and Occupy window) for the screen.
int BorderBottom
BorderBottom config var.
int BorderRight
BorderRight config var.
bool workSpaceManagerActive
Whether the WSM is being shown.
int BorderLeft
BorderLeft config var.
int rootw
Copy of DisplayWidth(dpy, screen).
int d_depth
Copy of DefaultDepth(dpy, screen).
int screen
Which screen (i.e., the x after the dot in ":0.x").
int rooth
Copy of DisplayHeight(dpy, screen).
Info and control for every X Window we take over.
bool iswspmgr
This is a workspace manager window.
bool isiconmgr
This is an icon manager window.
Window w
The actual X Window handle.
int zoomed
ZOOM_NONE || function causing zoom.
struct Icon * icon
The current icon.
int occupation
Workspaces the window is in (bitmap).
struct VirtualScreen * vs
Where the window is currently mapped (may be NULL).
bool mapped
Is the window mapped ?
struct WList * iconmanagerlist
List of the icon managers the window is in.
struct VirtualScreen * parent_vs
Where the window is parented. Always set.
struct TwmWindow::_names names
Various sources of window/icon names. "
bool squeezed
Is the window squeezed ?
struct VirtualScreen * next
struct WorkSpaceWindow * wsw
static int max(int a, int b)
void DeIconify(TwmWindow *tmp_win)
void Squeeze(TwmWindow *tmp_win)
void SetFocus(TwmWindow *tmp_win, Time tim)
void fullzoom(TwmWindow *tmp_win, int func)
void apply_window_icon_name(TwmWindow *win)
[Re]set and apply changes to a window's icon name.
void FreeWMPropertyString(char *prop)
TwmWindow * GetTwmWindow(Window w)
void WarpToWindow(TwmWindow *t, bool must_raise)
void apply_window_name(TwmWindow *win)
[Re]set and apply changes to a window's name.
char * GetWMPropertyString(Window w, Atom prop)
void GotoWorkSpaceByNumber(VirtualScreen *vs, int workspacenum)
void ShowBackground(VirtualScreen *vs, int newstate)