git.strcat.st

/strcat/wm.git/ - summarytreelogarchivereleases

subject
move keybind logic into wmc.c; wmc command manages windows via scripts or hotkeys
commit
f2332dfb1b376c0437d4e25c27f04a53ef92558a
date
2026-04-20T23:19:53Z
message
diff
 Makefile |  8 +++++--
 wm.c     | 74 +++++++++++++++++++++++++++++++---------------------------------
 wmc.c    | 49 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 91 insertions(+), 40 deletions(-)

diff --git a/Makefile b/Makefile
index 39a96ab..1260360 100644
--- a/Makefile
+++ b/Makefile
@@ -3,12 +3,16 @@ CPPFLAGS = -I/usr/X11R6/include
 LDFLAGS = -L/usr/X11R6/lib
 LDLIBS = -lX11
 
-all: wm
+all: wm wmc
 
 wm: wm.c
 	cc $(CPPFLAGS) $(CFLAGS) -o wm wm.c $(LDFLAGS) $(LDLIBS)
+
+wmc: wmc.c
+	cc $(CPPFLAGS) $(CFLAGS) -o wmc wmc.c $(LDFLAGS) $(LDLIBS)
+
 run: wm
 	./wm
 
 clean:
-	rm -f wm
+	rm -f wm wmc
diff --git a/wm.c b/wm.c
index d21cbfd..24156e2 100644
--- a/wm.c
+++ b/wm.c
@@ -1,9 +1,10 @@
 #include <X11/Xlib.h>
-#include <X11/keysym.h>
 
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define MODKEY Mod1Mask
 #define MAXWINS 4096
+#define CMD_WS 1
+#define CMD_MOVE 2
 
 static Window wins[MAXWINS];
 static int ws[MAXWINS], nwin, curws;
@@ -23,19 +24,40 @@ getidx(Window w)
 	return nwin++;
 }
 
+static void
+showws(Display *dpy, Window root)
+{
+	Window rootret, parent, *children;
+	int i, j, idx;
+
+	if (XQueryTree(dpy, root, &rootret, &parent, &children, (unsigned int *)&j)) {
+	    for (i = 0; i < j; i++) {
+	        idx = getidx(children[i]);
+	        if (idx >= 0) {
+	            if (ws[idx] == curws)
+	                XMapWindow(dpy, children[i]);
+	            else
+	                XUnmapWindow(dpy, children[i]);
+	        }
+	    }
+	    if (children != None)
+	        XFree(children);
+	}
+}
+
 int
 main(void)
 {
 	Display *dpy;
 	Window root;
 	Window dragwin;
-	Window rootret, parent, *children, focus;
+	Window focus;
 	XWindowAttributes attr;
 	XButtonEvent start;
 	XEvent ev;
+	Atom ctl;
 	int dragging;
-	int i, j, revert;
-	KeySym ks;
+	int i, j;
 
 	dragging = 0;
 	dragwin = None;
@@ -43,15 +65,8 @@ main(void)
 	    return 1;
 
 	root = DefaultRootWindow(dpy);
+	ctl = XInternAtom(dpy, "_WM_CTL", False);
 
-	XGrabKey(dpy, XKeysymToKeycode(dpy, XK_F1), MODKEY, root,
-	    True, GrabModeAsync, GrabModeAsync);
-	for (i = 0; i < 9; i++) {
-	    XGrabKey(dpy, XKeysymToKeycode(dpy, XK_1 + i), MODKEY, root,
-	        True, GrabModeAsync, GrabModeAsync);
-	    XGrabKey(dpy, XKeysymToKeycode(dpy, XK_1 + i), MODKEY | ShiftMask,
-	        root, True, GrabModeAsync, GrabModeAsync);
-	}
 	XGrabButton(dpy, 1, MODKEY, root, True, ButtonPressMask, GrabModeAsync,
 	    GrabModeAsync, None, None);
 	XGrabButton(dpy, 3, MODKEY, root, True, ButtonPressMask, GrabModeAsync,
@@ -59,39 +74,22 @@ main(void)
 
 	for (;;) {
 	    XNextEvent(dpy, &ev);
-	    if (ev.type == KeyPress) {
-	        ks = XLookupKeysym(&ev.xkey, 0);
-	        if (ks >= XK_1 && ks <= XK_9) {
-	            i = (int)(ks - XK_1);
-	            if (ev.xkey.state & ShiftMask) {
-	                focus = ev.xkey.subwindow;
-	                if (focus == None)
-	                    XGetInputFocus(dpy, &focus, &revert);
+	    if (ev.type == ClientMessage && ev.xclient.message_type == ctl) {
+	        i = (int)ev.xclient.data.l[1];
+	        if (i >= 0 && i < 9) {
+	            if (ev.xclient.data.l[0] == CMD_WS && i != curws) {
+	                curws = i;
+	                showws(dpy, root);
+	            } else if (ev.xclient.data.l[0] == CMD_MOVE) {
+	                XGetInputFocus(dpy, &focus, &j);
 	                j = getidx(focus);
 	                if (j >= 0) {
 	                    ws[j] = i;
 	                    if (i != curws)
 	                        XUnmapWindow(dpy, focus);
 	                }
-	            } else if (i != curws) {
-	                curws = i;
-	                if (XQueryTree(dpy, root, &rootret, &parent, &children,
-	                    (unsigned int *)&j)) {
-	                    for (i = 0; i < j; i++) {
-	                        revert = getidx(children[i]);
-	                        if (revert >= 0) {
-	                            if (ws[revert] == curws)
-	                                XMapWindow(dpy, children[i]);
-	                            else
-	                                XUnmapWindow(dpy, children[i]);
-	                        }
-	                    }
-	                    if (children != None)
-	                        XFree(children);
-	                }
 	            }
-	        } else if (ks == XK_F1 && ev.xkey.subwindow != None)
-	            XRaiseWindow(dpy, ev.xkey.subwindow);
+	        }
 	    } else if (ev.type == ButtonPress && ev.xbutton.subwindow != None) {
 	        dragwin = ev.xbutton.subwindow;
 	        j = getidx(dragwin);
diff --git a/wmc.c b/wmc.c
new file mode 100644
index 0000000..cd1d860
--- /dev/null
+++ b/wmc.c
@@ -0,0 +1,49 @@
+#include <X11/Xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CMD_WS 1
+#define CMD_MOVE 2
+
+int
+main(int argc, char **argv)
+{
+	Display *dpy;
+	Window root;
+	XEvent ev;
+	Atom ctl;
+	int cmd, ws;
+	char *end;
+
+	cmd = CMD_WS;
+	if (argc == 2)
+	    ws = (int)strtol(argv[1], &end, 10);
+	else if (argc == 3 && !strcmp(argv[1], "move")) {
+	    cmd = CMD_MOVE;
+	    ws = (int)strtol(argv[2], &end, 10);
+	} else if (argc == 3 && !strcmp(argv[1], "ws"))
+	    ws = (int)strtol(argv[2], &end, 10);
+	else {
+	    fprintf(stderr, "usage: wmc [ws] 1-9 | wmc move 1-9\n");
+	    return 1;
+	}
+	if (*end != '\0' || ws < 1 || ws > 9)
+	    return 1;
+	if ((dpy = XOpenDisplay(NULL)) == NULL)
+	    return 1;
+	root = DefaultRootWindow(dpy);
+	ctl = XInternAtom(dpy, "_WM_CTL", False);
+	memset(&ev, 0, sizeof(ev));
+	ev.xclient.type = ClientMessage;
+	ev.xclient.window = root;
+	ev.xclient.message_type = ctl;
+	ev.xclient.format = 32;
+	ev.xclient.data.l[0] = cmd;
+	ev.xclient.data.l[1] = ws - 1;
+	XSendEvent(dpy, root, False, SubstructureNotifyMask, &ev);
+	XFlush(dpy);
+	XCloseDisplay(dpy);
+	return 0;
+}