git.strcat.st

/strcat/wm.git/ - summarytreelogarchivereleases

subject
fix pop ups unable to be chosen with left click
commit
42ff40ea288cb84d4cfdae8adb35d566cbf34f16
date
2026-04-28T19:46:35Z
message
diff
 wm.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 75 insertions(+), 12 deletions(-)

diff --git a/wm.c b/wm.c
index 12c97de..f7a3f2b 100644
--- a/wm.c
+++ b/wm.c
@@ -8,9 +8,11 @@
 #define cmd_move 2
 #define cmd_kill 3
 #define num_workspaces 9
+#define modifier_variants 4
 
 static Window windows[max_windows];
 static int window_workspace[max_windows], window_count, current_workspace;
+static int is_root_child(Display *display, Window root_window, Window window);
 
 static int
 get_window_index(Window window)
@@ -27,6 +29,57 @@ get_window_index(Window window)
 	return window_count++;
 }
 
+static void
+remove_window(Window window)
+{
+	int i;
+
+	for (i = 0; i < window_count; i++) {
+	    if (windows[i] == window) {
+	        for (; i < window_count - 1; i++) {
+	            windows[i] = windows[i + 1];
+	            window_workspace[i] = window_workspace[i + 1];
+	        }
+	        window_count--;
+	        return;
+	    }
+	}
+}
+
+static void
+grab_button_variants(Display *display, unsigned int button, unsigned int modifiers,
+    Window root_window, int pointer_mode)
+{
+	unsigned int extra_mods[modifier_variants];
+	int i;
+
+	extra_mods[0] = 0;
+	extra_mods[1] = LockMask;
+	extra_mods[2] = Mod2Mask;
+	extra_mods[3] = LockMask | Mod2Mask;
+	for (i = 0; i < modifier_variants; i++)
+	    XGrabButton(display, button, modifiers | extra_mods[i], root_window, True,
+	        ButtonPressMask, pointer_mode, GrabModeAsync, None, None);
+}
+
+static void
+get_window_attrs(Display *display, Window window, XWindowAttributes *window_attrs)
+{
+	if (!XGetWindowAttributes(display, window, window_attrs))
+	    window_attrs->override_redirect = True;
+}
+
+static int
+is_managed_window(Display *display, Window root_window, Window window)
+{
+	XWindowAttributes window_attrs;
+
+	if (!is_root_child(display, root_window, window))
+	    return 0;
+	get_window_attrs(display, window, &window_attrs);
+	return !window_attrs.override_redirect;
+}
+
 static void
 track_windows(Display *display, Window root_window)
 {
@@ -35,7 +88,8 @@ track_windows(Display *display, Window root_window)
 
 	if (XQueryTree(display, root_window, &root_return, &parent, &children, (unsigned int *)&j)) {
 	    for (i = 0; i < j; i++)
-	        get_window_index(children[i]);
+	        if (is_managed_window(display, root_window, children[i]))
+	            get_window_index(children[i]);
 	    if (children != None)
 	        XFree(children);
 	}
@@ -64,6 +118,8 @@ show_workspace(Display *display, Window root_window)
 
 	if (XQueryTree(display, root_window, &root_return, &parent, &children, (unsigned int *)&j)) {
 	    for (i = 0; i < j; i++) {
+	        if (!is_managed_window(display, root_window, children[i]))
+	            continue;
 	        window_index = get_window_index(children[i]);
 	        if (window_index >= 0) {
 	            if (window_workspace[window_index] == current_workspace)
@@ -103,16 +159,9 @@ main(void)
 	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,
-	    GrabModeAsync, None, None);
+	grab_button_variants(display, 1, 0, root_window, GrabModeSync);
+	grab_button_variants(display, 1, mod_key, root_window, GrabModeAsync);
+	grab_button_variants(display, 3, mod_key, root_window, GrabModeAsync);
 
 	for (;;) {
 	    XNextEvent(display, &event);
@@ -147,20 +196,32 @@ main(void)
 	                }
 	            }
 	        }
+	    } else if (event.type == DestroyNotify) {
+	        remove_window(event.xdestroywindow.window);
+	        ewmh_sync(display, root_window, windows, window_workspace, window_count);
 	    } else if (event.type == ButtonPress && event.xbutton.subwindow != None) {
 	        drag_window = event.xbutton.subwindow;
+	        if (!is_managed_window(display, root_window, drag_window)) {
+	            if (!(event.xbutton.state & mod_key))
+	                XAllowEvents(display, ReplayPointer, event.xbutton.time);
+	            continue;
+	        }
 	        ewmh_set_active_window(display, root_window, drag_window);
 	        XSetInputFocus(display, drag_window, RevertToPointerRoot, CurrentTime);
 	        j = get_window_index(drag_window);
 	        if (j >= 0)
 	            window_workspace[j] = current_workspace;
 	        ewmh_sync(display, root_window, windows, window_workspace, window_count);
+	        if (!(event.xbutton.state & mod_key) && event.xbutton.button == 1) {
+	            XAllowEvents(display, ReplayPointer, event.xbutton.time);
+	            continue;
+	        }
 	        if (!(event.xbutton.state & mod_key))
 	            continue;
 	        XGrabPointer(display, drag_window, True,
 	            PointerMotionMask | ButtonReleaseMask,
 	            GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
-	        XGetWindowAttributes(display, drag_window, &window_attrs);
+	        get_window_attrs(display, drag_window, &window_attrs);
 	        drag_start = event.xbutton;
 	        if (drag_start.button == 3) {
 	            drag_start.x_root = window_attrs.x + window_attrs.width - 1;
@@ -169,6 +230,8 @@ main(void)
 	                drag_start.x_root, drag_start.y_root);
 	        }
 	        is_dragging = 1;
+	    } else if (event.type == ButtonPress && event.xbutton.subwindow == None) {
+	        XAllowEvents(display, AsyncPointer, event.xbutton.time);
 	    } else if (event.type == MotionNotify && is_dragging) {
 	        int x_diff, y_diff;