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);