git.strcat.st

/strcat/wm.git/ - summarytreelogarchivereleases

subject
add EWMH patch
commit
13c2c18b18d740f3b18c04b47c6021cb6e5003a4
date
2026-04-21T00:55:10Z
message
diff
 patches/ewmh.patch | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 140 insertions(+)

diff --git a/patches/ewmh.patch b/patches/ewmh.patch
new file mode 100644
index 0000000..d940c21
--- /dev/null
+++ b/patches/ewmh.patch
@@ -0,0 +1,140 @@
+--- a/wm.c
++++ b/wm.c
+@@ -1,13 +1,21 @@
+ #include <X11/Xlib.h>
++#include <X11/Xatom.h>
+ 
++#include <string.h>
++
+ #define MAX(a, b) ((a) > (b) ? (a) : (b))
+ #define MODKEY Mod1Mask
+ #define MAXWINS 4096
+ #define CMD_WS 1
+ #define CMD_MOVE 2
++#define NUM_WS 9
+ 
+ static Window wins[MAXWINS];
+ static int ws[MAXWINS], nwin, curws;
++static Atom net_supported, net_number_of_desktops, net_current_desktop;
++static Atom net_active_window, net_client_list, net_wm_desktop;
++static Atom net_supporting_wm_check, net_wm_name, utf8_string;
++static Window wmcheck;
+ 
+ static int
+ getidx(Window w)
+@@ -25,6 +33,72 @@
+ }
+ 
+ static void
++setcardinal(Display *dpy, Window w, Atom a, unsigned long v)
++{
++	XChangeProperty(dpy, w, a, XA_CARDINAL, 32, PropModeReplace,
++	    (unsigned char *)&v, 1);
++}
++
++static void
++setwindow(Display *dpy, Window w, Atom a, Window v)
++{
++	XChangeProperty(dpy, w, a, XA_WINDOW, 32, PropModeReplace,
++	    (unsigned char *)&v, 1);
++}
++
++static void
++ewmhinit(Display *dpy, Window root)
++{
++	Atom supported[7];
++	char name[] = "wm";
++
++	net_supported = XInternAtom(dpy, "_NET_SUPPORTED", False);
++	net_number_of_desktops = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False);
++	net_current_desktop = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
++	net_active_window = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
++	net_client_list = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
++	net_wm_desktop = XInternAtom(dpy, "_NET_WM_DESKTOP", False);
++	net_supporting_wm_check = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
++	net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", False);
++	utf8_string = XInternAtom(dpy, "UTF8_STRING", False);
++	wmcheck = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
++	setwindow(dpy, root, net_supporting_wm_check, wmcheck);
++	setwindow(dpy, wmcheck, net_supporting_wm_check, wmcheck);
++	XChangeProperty(dpy, wmcheck, net_wm_name, utf8_string, 8, PropModeReplace,
++	    (unsigned char *)name, (int)(sizeof(name) - 1));
++	supported[0] = net_number_of_desktops;
++	supported[1] = net_current_desktop;
++	supported[2] = net_active_window;
++	supported[3] = net_client_list;
++	supported[4] = net_wm_desktop;
++	supported[5] = net_supporting_wm_check;
++	supported[6] = net_wm_name;
++	XChangeProperty(dpy, root, net_supported, XA_ATOM, 32, PropModeReplace,
++	    (unsigned char *)supported, 7);
++	setcardinal(dpy, root, net_number_of_desktops, NUM_WS);
++	setcardinal(dpy, root, net_current_desktop, 0);
++	setwindow(dpy, root, net_active_window, None);
++}
++
++static void
++ewmhsync(Display *dpy, Window root)
++{
++	unsigned long desktop;
++	int i;
++
++	if (nwin > 0)
++	    XChangeProperty(dpy, root, net_client_list, XA_WINDOW, 32, PropModeReplace,
++	        (unsigned char *)wins, nwin);
++	else
++	    XDeleteProperty(dpy, root, net_client_list);
++	for (i = 0; i < nwin; i++) {
++	    desktop = (unsigned long)ws[i];
++	    XChangeProperty(dpy, wins[i], net_wm_desktop, XA_CARDINAL, 32,
++	        PropModeReplace, (unsigned char *)&desktop, 1);
++	}
++}
++
++static void
+ showws(Display *dpy, Window root)
+ {
+ 	Window rootret, parent, *children;
+@@ -66,6 +140,8 @@
+ 
+ 	root = DefaultRootWindow(dpy);
+ 	ctl = XInternAtom(dpy, "_WM_CTL", False);
++	ewmhinit(dpy, root);
++	ewmhsync(dpy, root);
+ 
+ 	XGrabButton(dpy, 1, MODKEY, root, True, ButtonPressMask, GrabModeAsync,
+ 	    GrabModeAsync, None, None);
+@@ -76,25 +152,32 @@
+ 	    XNextEvent(dpy, &ev);
+ 	    if (ev.type == ClientMessage && ev.xclient.message_type == ctl) {
+ 	        i = (int)ev.xclient.data.l[1];
+-	        if (i >= 0 && i < 9) {
++	        if (i >= 0 && i < NUM_WS) {
+ 	            if (ev.xclient.data.l[0] == CMD_WS && i != curws) {
+ 	                curws = i;
+ 	                showws(dpy, root);
++	                setcardinal(dpy, root, net_current_desktop,
++	                    (unsigned long)curws);
++	                ewmhsync(dpy, root);
+ 	            } else if (ev.xclient.data.l[0] == CMD_MOVE) {
+ 	                XGetInputFocus(dpy, &focus, &j);
++	                setwindow(dpy, root, net_active_window, focus);
+ 	                j = getidx(focus);
+ 	                if (j >= 0) {
+ 	                    ws[j] = i;
+ 	                    if (i != curws)
+ 	                        XUnmapWindow(dpy, focus);
++	                    ewmhsync(dpy, root);
+ 	                }
+ 	            }
+ 	        }
+ 	    } else if (ev.type == ButtonPress && ev.xbutton.subwindow != None) {
+ 	        dragwin = ev.xbutton.subwindow;
++	        setwindow(dpy, root, net_active_window, dragwin);
+ 	        j = getidx(dragwin);
+ 	        if (j >= 0)
+ 	            ws[j] = curws;
++	        ewmhsync(dpy, root);
+ 	        XGrabPointer(dpy, dragwin, True,
+ 	            PointerMotionMask | ButtonReleaseMask,
+ 	            GrabModeAsync, GrabModeAsync, None, None, CurrentTime);