diff --git a/include/osd.h b/include/osd.h index a5c2a4cc..2af02ee6 100644 --- a/include/osd.h +++ b/include/osd.h @@ -53,7 +53,7 @@ void osd_begin(struct server *server, enum lab_cycle_dir direction); void osd_cycle(struct server *server, enum lab_cycle_dir direction); /* Closes the OSD */ -void osd_finish(struct server *server); +void osd_finish(struct server *server, bool switch_focus); /* Notify OSD about a destroying view */ void osd_on_view_destroy(struct view *view); diff --git a/src/input/keyboard.c b/src/input/keyboard.c index 8f7a3e81..f6b0114c 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -83,25 +83,6 @@ keyboard_get_all_modifiers(struct seat *seat) return modifiers; } -static void -end_cycling(struct server *server) -{ - should_cancel_cycling_on_next_key_release = false; - - if (server->input_mode != LAB_INPUT_STATE_WINDOW_SWITCHER) { - return; - } - - struct view *cycle_view = server->osd_state.cycle_view; - /* FIXME: osd_finish() transiently sets focus to the old surface */ - osd_finish(server); - /* Note that server->osd_state.cycle_view is cleared at this point */ - if (rc.window_switcher.unshade) { - view_set_shade(cycle_view, false); - } - desktop_focus_view(cycle_view, /*raise*/ true); -} - static struct wlr_seat_client * seat_client_from_keyboard_resource(struct wl_resource *resource) { @@ -163,19 +144,19 @@ handle_modifiers(struct wl_listener *listener, void *data) bool window_switcher_active = server->input_mode == LAB_INPUT_STATE_WINDOW_SWITCHER; - if (window_switcher_active || seat->workspace_osd_shown_by_modifier) { - if (!keyboard_get_all_modifiers(seat)) { - if (window_switcher_active) { - if (key_state_nr_bound_keys()) { - should_cancel_cycling_on_next_key_release = true; - } else { - end_cycling(server); - } - } - if (seat->workspace_osd_shown_by_modifier) { - workspaces_osd_hide(seat); + if ((window_switcher_active || seat->workspace_osd_shown_by_modifier) + && !keyboard_get_all_modifiers(seat)) { + if (window_switcher_active) { + if (key_state_nr_bound_keys()) { + should_cancel_cycling_on_next_key_release = true; + } else { + should_cancel_cycling_on_next_key_release = false; + osd_finish(server, /*switch_focus*/ true); } } + if (seat->workspace_osd_shown_by_modifier) { + workspaces_osd_hide(seat); + } } if (!input_method_keyboard_grab_forward_modifiers(keyboard)) { @@ -406,7 +387,8 @@ handle_key_release(struct server *server, uint32_t evdev_keycode) * event it gets stuck on repeat. */ if (should_cancel_cycling_on_next_key_release) { - end_cycling(server); + should_cancel_cycling_on_next_key_release = false; + osd_finish(server, /*switch_focus*/ true); } /* @@ -479,7 +461,7 @@ handle_cycle_view_key(struct server *server, struct keyinfo *keyinfo) for (int i = 0; i < keyinfo->translated.nr_syms; i++) { if (keyinfo->translated.syms[i] == XKB_KEY_Escape) { /* Esc deactivates window switcher */ - osd_finish(server); + osd_finish(server, /*switch_focus*/ false); return true; } if (keyinfo->translated.syms[i] == XKB_KEY_Up diff --git a/src/osd/osd.c b/src/osd/osd.c index e436c19e..865a58dd 100644 --- a/src/osd/osd.c +++ b/src/osd/osd.c @@ -119,7 +119,7 @@ osd_on_view_destroy(struct view *view) */ if (osd_state->cycle_view == view || !osd_state->cycle_view) { /* osd_finish() additionally resets cycle_view to NULL */ - osd_finish(view->server); + osd_finish(view->server, /*switch_focus*/ false); } } @@ -201,11 +201,17 @@ osd_cycle(struct server *server, enum lab_cycle_dir direction) } void -osd_finish(struct server *server) +osd_finish(struct server *server, bool switch_focus) { + if (server->input_mode != LAB_INPUT_STATE_WINDOW_SWITCHER) { + return; + } + restore_preview_node(server); + /* FIXME: this sets focus to the old surface even with switch_focus=true */ seat_focus_override_end(&server->seat); + struct view *cycle_view = server->osd_state.cycle_view; server->osd_state.preview_node = NULL; server->osd_state.preview_anchor = NULL; server->osd_state.cycle_view = NULL; @@ -221,6 +227,13 @@ osd_finish(struct server *server) /* Hiding OSD may need a cursor change */ cursor_update_focus(server); + + if (switch_focus && cycle_view) { + if (rc.window_switcher.unshade) { + view_set_shade(cycle_view, false); + } + desktop_focus_view(cycle_view, /*raise*/ true); + } } static void @@ -286,7 +299,7 @@ update_osd(struct server *server) } if (!wl_array_len(&views) || !server->osd_state.cycle_view) { - osd_finish(server); + osd_finish(server, /*switch_focus*/ false); goto out; }