]> git.mdlowis.com Git - proto/labwc.git/commitdiff
seat: move session-lock check down to seat_focus() level
authorJohn Lindgren <john@jlindgren.net>
Sun, 15 Oct 2023 06:59:58 +0000 (02:59 -0400)
committerJohan Malm <johanmalm@users.noreply.github.com>
Sun, 15 Oct 2023 20:32:41 +0000 (21:32 +0100)
We were checking for a locked session in desktop_focus_view(), but there
are several other call sites of seat_focus_surface() which were missing
such a check. Any one of those could cause the lock screen to lose focus
(making the session impossible to unlock) or another surface to gain it
(breaching the session lock).

To fix the issue, make any call to seat_focus_surface() no-op when the
session is locked. Add a specific seat_focus_lock_surface() function
which is the only way to bypass the check and is called only from
session-lock.c.

include/labwc.h
src/desktop.c
src/seat.c
src/session-lock.c

index 8d0a1392e63be78926c81c8dfbd4742049d272fb..54fbe96052d3c9e19850663be904f365c42a76f8 100644 (file)
@@ -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,
index 3672e270c9adc914ed3d2372ce00b41f9d51fa97..607da49c8194734ba23dafb03644eec2d8a80612 100644 (file)
@@ -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);
        }
index 7852180dcc2db9babd9cfbf201577e237d755ea6..4387b8171c4346e6b933a8ca2d8a1d6c58d54a3f 100644 (file)
@@ -472,13 +472,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)
@@ -490,10 +504,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);
@@ -503,12 +517,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
@@ -519,7 +539,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;
        }
index d3a3ca8a06bdbbaa92fc5b369d963213649087be..0f4f8ef6c172d50dbd1dd3fe2077539c90341a6f 100644 (file)
@@ -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