From: Matthias Kruk Date: Mon, 24 May 2021 21:51:53 +0000 (+0900) Subject: Fix a number of focus-related issues X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=fce25b97110b3177c64a2f0df13c91c6ba0c0f05;p=mwm Fix a number of focus-related issues 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 --- diff --git a/client.c b/client.c index 89c4549..57167a2 100644 --- 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 90c1556..11ca98b 100644 --- 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)); } diff --git a/workspace.c b/workspace.c index cb38d82..e8d7d8c 100644 --- a/workspace.c +++ b/workspace.c @@ -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); }