git.strcat.st

/strcat/wm.git/ - summarytreelogarchivereleases

subject
replace windows focus on hover with click to focus
commit
5bf01c79a545b8ec06a964b5ab365ae9902308b6
date
2026-04-28T18:13:55Z
message
diff
 wm.c  | 47 +++++++++++++++++++++--------------------------
 wmc.c | 12 ++++++++----
 2 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/wm.c b/wm.c
index c405bd2..12c97de 100644
--- a/wm.c
+++ b/wm.c
@@ -6,10 +6,9 @@
 #define max_windows 4096
 #define cmd_workspace 1
 #define cmd_move 2
+#define cmd_kill 3
 #define num_workspaces 9
 
-static const char focus_follows_mouse = 0;
-
 static Window windows[max_windows];
 static int window_workspace[max_windows], window_count, current_workspace;
 
@@ -83,34 +82,33 @@ main(void)
 {
 	Display *display;
 	Window root_window;
-	Window root_return;
-	Window pointer_child;
 	Window drag_window;
 	Window focused_window;
-	Window hover_focused_window;
 	XWindowAttributes window_attrs;
 	XButtonEvent drag_start;
 	XEvent event;
 	Atom control_atom;
 	int is_dragging;
-	int root_x, root_y, win_x, win_y;
-	unsigned int pointer_mask;
 	int i, j;
 
 	is_dragging = 0;
 	drag_window = None;
-	hover_focused_window = None;
 	if ((display = XOpenDisplay(NULL)) == NULL)
 	    return 1;
 
 	root_window = DefaultRootWindow(display);
 	control_atom = XInternAtom(display, "_WM_CTL", False);
-	XSelectInput(display, root_window, SubstructureNotifyMask |
-	    (focus_follows_mouse ? PointerMotionMask : 0));
+	XSelectInput(display, root_window, SubstructureNotifyMask);
 	track_windows(display, root_window);
 	ewmh_init(display, root_window);
 	ewmh_sync(display, root_window, windows, window_workspace, window_count);
 
+	XGrabButton(display, 1, 0, root_window, True, ButtonPressMask, GrabModeAsync,
+	    GrabModeAsync, None, None);
+	XGrabButton(display, 2, 0, root_window, True, ButtonPressMask, GrabModeAsync,
+	    GrabModeAsync, None, None);
+	XGrabButton(display, 3, 0, root_window, True, ButtonPressMask, GrabModeAsync,
+	    GrabModeAsync, None, None);
 	XGrabButton(display, 1, mod_key, root_window, True, ButtonPressMask, GrabModeAsync,
 	    GrabModeAsync, None, None);
 	XGrabButton(display, 3, mod_key, root_window, True, ButtonPressMask, GrabModeAsync,
@@ -119,15 +117,23 @@ main(void)
 	for (;;) {
 	    XNextEvent(display, &event);
 	    if (event.type == ClientMessage && event.xclient.message_type == control_atom) {
+	        int command;
+
+	        command = (int)event.xclient.data.l[0];
 	        i = (int)event.xclient.data.l[1];
-	        if (i >= 0 && i < num_workspaces) {
-	            if (event.xclient.data.l[0] == cmd_workspace && i != current_workspace) {
+	        if (command == cmd_kill) {
+	            XGetInputFocus(display, &focused_window, &j);
+	            if (!is_root_child(display, root_window, focused_window))
+	                continue;
+	            XKillClient(display, focused_window);
+	        } else if (i >= 0 && i < num_workspaces) {
+	            if (command == cmd_workspace && i != current_workspace) {
 	                track_windows(display, root_window);
 	                current_workspace = i;
 	                show_workspace(display, root_window);
 	                ewmh_set_current_desktop(display, root_window, current_workspace);
 	                ewmh_sync(display, root_window, windows, window_workspace, window_count);
-	            } else if (event.xclient.data.l[0] == cmd_move) {
+	            } else if (command == cmd_move) {
 	                XGetInputFocus(display, &focused_window, &j);
 	                if (!is_root_child(display, root_window, focused_window))
 	                    continue;
@@ -149,6 +155,8 @@ main(void)
 	        if (j >= 0)
 	            window_workspace[j] = current_workspace;
 	        ewmh_sync(display, root_window, windows, window_workspace, window_count);
+	        if (!(event.xbutton.state & mod_key))
+	            continue;
 	        XGrabPointer(display, drag_window, True,
 	            PointerMotionMask | ButtonReleaseMask,
 	            GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
@@ -173,19 +181,6 @@ main(void)
 	            window_attrs.y + (drag_start.button == 1 ? y_diff : 0),
 	            max_val(1, window_attrs.width + (drag_start.button == 3 ? x_diff : 0)),
 	            max_val(1, window_attrs.height + (drag_start.button == 3 ? y_diff : 0)));
-	    } else if (focus_follows_mouse && event.type == MotionNotify && !is_dragging) {
-	        while (XCheckTypedEvent(display, MotionNotify, &event))
-	            continue;
-	        if (!XQueryPointer(display, root_window, &root_return, &pointer_child,
-	                &root_x, &root_y, &win_x, &win_y, &pointer_mask))
-	            continue;
-	        if (pointer_child == None || pointer_child == hover_focused_window)
-	            continue;
-	        if (!is_root_child(display, root_window, pointer_child))
-	            continue;
-	        XSetInputFocus(display, pointer_child, RevertToPointerRoot, CurrentTime);
-	        ewmh_set_active_window(display, root_window, pointer_child);
-	        hover_focused_window = pointer_child;
 	    } else if (event.type == ButtonRelease) {
 	        is_dragging = 0;
 	        drag_window = None;
diff --git a/wmc.c b/wmc.c
index d30bb31..1ad063a 100644
--- a/wmc.c
+++ b/wmc.c
@@ -6,6 +6,7 @@
 
 #define cmd_workspace 1
 #define cmd_move 2
+#define cmd_kill 3
 
 int
 main(int argc, char **argv)
@@ -18,7 +19,10 @@ main(int argc, char **argv)
 	char *end_ptr;
 
 	command = cmd_workspace;
-	if (argc == 2)
+	workspace = 0;
+	if (argc == 2 && !strcmp(argv[1], "kill"))
+	    command = cmd_kill;
+	else if (argc == 2)
 	    workspace = (int)strtol(argv[1], &end_ptr, 10);
 	else if (argc == 3 && !strcmp(argv[1], "move")) {
 	    command = cmd_move;
@@ -26,10 +30,10 @@ main(int argc, char **argv)
 	} else if (argc == 3 && !strcmp(argv[1], "ws"))
 	    workspace = (int)strtol(argv[2], &end_ptr, 10);
 	else {
-	    fprintf(stderr, "usage: wmc [ws] 1-9 | wmc move 1-9\n");
+	    fprintf(stderr, "usage: wmc [ws] 1-9 | wmc move 1-9 | wmc kill\n");
 	    return 1;
 	}
-	if (*end_ptr != '\0' || workspace < 1 || workspace > 9)
+	if (command != cmd_kill && (*end_ptr != '\0' || workspace < 1 || workspace > 9))
 	    return 1;
 	if ((display = XOpenDisplay(NULL)) == NULL)
 	    return 1;
@@ -41,7 +45,7 @@ main(int argc, char **argv)
 	event.xclient.message_type = control_atom;
 	event.xclient.format = 32;
 	event.xclient.data.l[0] = command;
-	event.xclient.data.l[1] = workspace - 1;
+	event.xclient.data.l[1] = workspace > 0 ? workspace - 1 : 0;
 	XSendEvent(display, root_window, False, SubstructureNotifyMask, &event);
 	XFlush(display);
 	XCloseDisplay(display);