follow=keyboard: Fall back to follow=mouse instead of XDefaultScreen()

In dwm and similar window managers, it's common to often have empty
tags, and navigate to them with the intent to create clients there. If I
navigate to one of those empty tags with a dunst notification visible
and follow=keyboard set, the notification warps over to the default
screen.  If I then open a client, it then warps back, which is pretty
jarring.

This is mostly an artefact of the implementation of follow=keyboard --
if we fail to get a focused window, we use the default screen. However
this case isn't necessarily really a "failure" on window managers like
dwm where it's a common occurrence to end up with no clients on the
screen, whereas that would be significantly rarer on (say) GNOME or KDE.

A guess that's more likely to fit user expectations is falling back to
where the mouse pointer currently is, since this indicates the currently
focused monitor that the window manager would create a client on. This
avoids warping back to that monitor again when a client is created.
This commit is contained in:
Chris Down 2020-04-27 16:10:10 +01:00
parent 523d5e199e
commit e8fc45da63

View File

@ -303,6 +303,7 @@ bool window_is_fullscreen(Window window)
struct screen_info *get_active_screen(void)
{
int ret = 0;
bool force_follow_mouse = false;
if (settings.monitor > 0 && settings.monitor < screens_len) {
ret = settings.monitor;
goto sc_cleanup;
@ -321,7 +322,26 @@ struct screen_info *get_active_screen(void)
Window root =
RootWindow(xctx.dpy, DefaultScreen(xctx.dpy));
if (settings.f_mode == FOLLOW_MOUSE) {
if (settings.f_mode == FOLLOW_KEYBOARD) {
Window focused = get_focused_window();
if (focused == 0) {
/*
* This can happen in the case that the user
* just has the root window open, eg. in empty
* tags in dwm or similar window managers. In
* that case, fall back to FOLLOW_MOUSE, since
* it probably still has the right screen.
*/
force_follow_mouse = true;
} else {
Window child_return;
XTranslateCoordinates(xctx.dpy, focused, root,
0, 0, &x, &y, &child_return);
}
}
if (settings.f_mode == FOLLOW_MOUSE || force_follow_mouse) {
int dummy;
unsigned int dummy_ui;
Window dummy_win;
@ -337,21 +357,6 @@ struct screen_info *get_active_screen(void)
&dummy_ui);
}
if (settings.f_mode == FOLLOW_KEYBOARD) {
Window focused = get_focused_window();
if (focused == 0) {
/* something went wrong. Fall back to default */
ret = XDefaultScreen(xctx.dpy);
goto sc_cleanup;
}
Window child_return;
XTranslateCoordinates(xctx.dpy, focused, root,
0, 0, &x, &y, &child_return);
}
for (int i = 0; i < screens_len; i++) {
if (INRECT(x, y, screens[i].x, screens[i].y,
screens[i].w, screens[i].h)) {