diff --git a/include/labwc.h b/include/labwc.h index 8d0a1392..54fbe960 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -432,6 +432,13 @@ void seat_init(struct server *server); void seat_finish(struct server *server); void seat_reconfigure(struct server *server); void seat_focus_surface(struct seat *seat, struct wlr_surface *surface); + +/** + * seat_focus_lock_surface() - ONLY to be called from session-lock.c to + * focus lock screen surfaces. Use seat_focus_surface() otherwise. + */ +void seat_focus_lock_surface(struct seat *seat, struct wlr_surface *surface); + void seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer); void seat_set_pressed(struct seat *seat, struct view *view, struct wlr_scene_node *node, struct wlr_surface *surface, diff --git a/src/desktop.c b/src/desktop.c index f6c94dd8..39f19ee3 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -46,12 +46,6 @@ desktop_focus_view(struct view *view, bool raise) return; } - struct server *server = view->server; - if (input_inhibit_blocks_surface(&server->seat, view->surface->resource) - || server->session_lock) { - return; - } - if (view->minimized) { /* * Unminimizing will map the view which triggers a call to this @@ -80,7 +74,7 @@ desktop_focus_view(struct view *view, bool raise) * that expect to be able to control focus themselves, but can't * under labwc since it's disallowed at the wlroots level. */ - struct seat *seat = &server->seat; + struct seat *seat = &view->server->seat; if (view->surface != seat->seat->keyboard_state.focused_surface) { seat_focus_surface(seat, view->surface); } diff --git a/src/seat.c b/src/seat.c index 9dc47d27..b1404a15 100644 --- a/src/seat.c +++ b/src/seat.c @@ -489,13 +489,27 @@ seat_reconfigure(struct server *server) } static void -seat_focus(struct seat *seat, struct wlr_surface *surface) +seat_focus(struct seat *seat, struct wlr_surface *surface, bool is_lock_surface) { + /* + * Respect session lock. This check is critical, DO NOT REMOVE. + * It should also come before the !surface condition, or the + * lock screen may lose focus and become impossible to unlock. + */ + struct server *server = seat->server; + if (server->session_lock && !is_lock_surface) { + return; + } + if (!surface) { wlr_seat_keyboard_notify_clear_focus(seat->seat); return; } - struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; + + /* Respect input inhibit (also used by some lock screens) */ + if (input_inhibit_blocks_surface(seat, surface->resource)) { + return; + } /* * Key events associated with keybindings (both pressed and released) @@ -507,10 +521,10 @@ seat_focus(struct seat *seat, struct wlr_surface *surface) uint32_t *pressed_sent_keycodes = key_state_pressed_sent_keycodes(); int nr_pressed_sent_keycodes = key_state_nr_pressed_sent_keycodes(); + struct wlr_keyboard *kb = &seat->keyboard_group->keyboard; wlr_seat_keyboard_notify_enter(seat->seat, surface, pressed_sent_keycodes, nr_pressed_sent_keycodes, &kb->modifiers); - struct server *server = seat->server; struct wlr_pointer_constraint_v1 *constraint = wlr_pointer_constraints_v1_constraint_for_surface(server->constraints, surface, seat->seat); @@ -520,12 +534,18 @@ seat_focus(struct seat *seat, struct wlr_surface *surface) void seat_focus_surface(struct seat *seat, struct wlr_surface *surface) { - /* Respect layer-shell exlusive keyboard-interactivity. */ + /* Respect layer-shell exclusive keyboard-interactivity. */ if (seat->focused_layer && seat->focused_layer->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) { return; } - seat_focus(seat, surface); + seat_focus(seat, surface, /*is_lock_surface*/ false); +} + +void +seat_focus_lock_surface(struct seat *seat, struct wlr_surface *surface) +{ + seat_focus(seat, surface, /*is_lock_surface*/ true); } void @@ -536,7 +556,7 @@ seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer) desktop_focus_topmost_view(seat->server); return; } - seat_focus(seat, layer->surface); + seat_focus(seat, layer->surface, /*is_lock_surface*/ false); if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { seat->focused_layer = layer; } diff --git a/src/session-lock.c b/src/session-lock.c index d3a3ca8a..0f4f8ef6 100644 --- a/src/session-lock.c +++ b/src/session-lock.c @@ -29,7 +29,7 @@ static void focus_surface(struct session_lock *lock, struct wlr_surface *focused) { lock->focused = focused; - seat_focus_surface(&g_server->seat, focused); + seat_focus_lock_surface(&g_server->seat, focused); } static void