]> git.corax.cc Git - mwm/commitdiff
Fix a number of focus-related issues
authorMatthias Kruk <m@m10k.eu>
Mon, 24 May 2021 21:51:53 +0000 (06:51 +0900)
committerMatthias Kruk <m@m10k.eu>
Mon, 24 May 2021 22:29:03 +0000 (07:29 +0900)
The are a couple of issues with the way focusing is implemented (or
rather, neglected):
 - Focusing on a different client does not change the keyboard focus
 - The keyboard focus does not follow the pointer
 - The keyboard focus does not change when clicking on a window
 - The pointer does not follow the focus

This commit fixes the above issues by making the following changes:
 - Focus on a client when the pointer enters it
 - When focusing on a client, also move the keyboard focus
 - When focusing on a client, move the pointer over the client

client.c
mwm.c
workspace.c

index 89c4549804c9049a83fa54d7c3bdfde1ca745fc3..57167a2f0626f9b528bb54585326d6c124d65abd 100644 (file)
--- a/client.c
+++ b/client.c
@@ -8,6 +8,7 @@
 #include "workspace.h"
 #include "mwm.h"
 #include "monitor.h"
+#include "kbptr.h"
 
 struct client {
        Window window;
@@ -267,11 +268,41 @@ int client_needs_redraw(struct client *client)
 
 int client_focus(struct client *client)
 {
+       Display *display;
+       Window dontcare_w;
+       int dontcare_i;
+       unsigned int dontcare_u;
+       struct geom extents;
+       int x;
+       int y;
+
        if(!client) {
                return(-EINVAL);
        }
 
-       XSetInputFocus(mwm_get_display(__mwm), client->window, RevertToPointerRoot, CurrentTime);
+       display = mwm_get_display(__mwm);
+
+       XSetInputFocus(display, client->window, RevertToPointerRoot, CurrentTime);
+
+       /*
+        * If the pointer is not over the focused client, move it over the client.
+        * Because of the border, the window is actually slightly larger than what
+        * the client geometry says, so we need to add some tolerance, otherwise
+        * the pointer would suddenly jump to the center of the window when the
+        * user is moving the pointer over the border.
+        */
+       XQueryPointer(display, client->window, &dontcare_w, &dontcare_w,
+                     &x, &y, &dontcare_i, &dontcare_i, &dontcare_u);
+
+       extents.x = client->geom.x - 1;
+       extents.y = client->geom.y - 1;
+       extents.w = client->geom.x + client->geom.w + 1;
+       extents.h = client->geom.y + client->geom.h + 1;
+
+       if(!(x >= extents.x && y >= extents.y &&
+            x <= extents.w && y <= extents.h)) {
+               kbptr_move(__mwm, client, KBPTR_CENTER);
+       }
 
        return(0);
 }
diff --git a/mwm.c b/mwm.c
index 90c15565d443e1ba675087072456cd26dac55186..11ca98bdeafd8aa243582df4b34bedb90a20871b 100644 (file)
--- a/mwm.c
+++ b/mwm.c
@@ -1289,6 +1289,10 @@ int mwm_attach_client(struct mwm *mwm, struct client *client)
                (void*)client, (void*)workspace);
 #endif /* MWM_DEBUG */
 
+        XSelectInput(mwm->display, client_get_window(client),
+                    EnterWindowMask | FocusChangeMask |
+                    PropertyChangeMask | StructureNotifyMask);
+
        return(workspace_attach_client(workspace, client));
 }
 
index cb38d82ae8f2abcfcccfc079a4e4966b0d8ae4b8..e8d7d8c06882767c9aec7963297cb3a88f102db3 100644 (file)
@@ -176,7 +176,11 @@ int workspace_focus_client(struct workspace *workspace, struct client *client)
                return(-EINVAL);
        }
 
-       workspace->focused = client;
+       if(workspace->focused != client) {
+               workspace->focused = client;
+               workspace_needs_redraw(workspace);
+       }
+
        return(0);
 }