cycle: fix spurious focus changes on finishing window switcher

As described in the `FIXME` comment in `cycle.c`, we had spurious focus
changes where the keyboard focus is momentarily given to the previously
focused window when finishing the window switcher, an then it is given
to the selected window.

This commit fixes this by adding a parameter in
`seat_focus_override_end()` to avoid restoring the focus to the
previously focused window.

I also removed the check for `!seat->seat->keyboard_state.focused_surface`
in `seat_focus_override_end()`. I thought it was necessary to avoid
updating the keyboard focus if the focus was given to a session-lock
surface before e.g. finishing window switching, but `seat_focus()` is
no-op in that case anyway.
This commit is contained in:
tokyo4j 2026-01-29 18:00:43 +09:00 committed by Johan Malm
parent 83b619c285
commit 4819f47f98
5 changed files with 12 additions and 11 deletions

View file

@ -397,10 +397,10 @@ void seat_output_layout_changed(struct seat *seat);
void seat_focus_override_begin(struct seat *seat, enum input_mode input_mode,
enum lab_cursors cursor_shape);
/*
* Restore the pointer/keyboard focus which was cleared in
* seat_focus_override_begin().
* If restore_focus=true, restore the pointer/keyboard focus which was cleared
* in seat_focus_override_begin().
*/
void seat_focus_override_end(struct seat *seat);
void seat_focus_override_end(struct seat *seat, bool restore_focus);
/**
* interactive_anchor_to_cursor() - repositions the geometry to remain

View file

@ -204,8 +204,7 @@ cycle_finish(struct server *server, bool switch_focus)
struct view *selected_view = server->cycle.selected_view;
destroy_cycle(server);
/* FIXME: this sets focus to the old surface even with switch_focus=true */
seat_focus_override_end(&server->seat);
seat_focus_override_end(&server->seat, /*restore_focus*/ false);
/* Hiding OSD may need a cursor change */
cursor_update_focus(server);

View file

@ -325,5 +325,5 @@ interactive_cancel(struct view *view)
view->server->grabbed_view = NULL;
/* Restore keyboard/pointer focus */
seat_focus_override_end(&view->server->seat);
seat_focus_override_end(&view->server->seat, /*restore_focus*/ true);
}

View file

@ -1430,7 +1430,7 @@ menu_execute_item(struct menuitem *item)
struct server *server = item->parent->server;
menu_close(server->menu_current);
server->menu_current = NULL;
seat_focus_override_end(&server->seat);
seat_focus_override_end(&server->seat, /*restore_focus*/ true);
/*
* We call the actions after closing the menu so that virtual keyboard
@ -1533,7 +1533,7 @@ menu_close_root(struct server *server)
menu_close(server->menu_current);
server->menu_current = NULL;
reset_pipemenus(server);
seat_focus_override_end(&server->seat);
seat_focus_override_end(&server->seat, /*restore_focus*/ true);
}
void

View file

@ -902,12 +902,12 @@ seat_focus_override_begin(struct seat *seat, enum input_mode input_mode,
}
void
seat_focus_override_end(struct seat *seat)
seat_focus_override_end(struct seat *seat, bool restore_focus)
{
seat->server->input_mode = LAB_INPUT_STATE_PASSTHROUGH;
if (seat->focus_override.surface) {
if (!seat->seat->keyboard_state.focused_surface) {
if (restore_focus) {
seat_focus(seat, seat->focus_override.surface,
/*replace_exclusive_layer*/ false,
/*is_lock_surface*/ false);
@ -916,5 +916,7 @@ seat_focus_override_end(struct seat *seat)
seat->focus_override.surface = NULL;
}
cursor_update_focus(seat->server);
if (restore_focus) {
cursor_update_focus(seat->server);
}
}