From f769203238e62bb909ea1e035e41ba1e586c8876 Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Sun, 14 Sep 2025 16:13:08 +0200 Subject: [PATCH 1/2] Fixes session lock surfaces not being able to switch focused output --- include/sway/server.h | 2 ++ sway/input/seat.c | 18 ++++++++++++++++++ sway/lock.c | 17 +++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/include/sway/server.h b/include/sway/server.h index f50d48f05..a5b6d3320 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -178,6 +178,8 @@ void sway_session_lock_add_output(struct sway_session_lock *lock, struct sway_output *output); bool sway_session_lock_has_surface(struct sway_session_lock *lock, struct wlr_surface *surface); +void sway_session_lock_focus_output(struct sway_session_lock *lock, + struct sway_output *output); void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data); #if WLR_HAS_XWAYLAND void handle_xwayland_surface(struct wl_listener *listener, void *data); diff --git a/sway/input/seat.c b/sway/input/seat.c index 1b63f625b..ba64babe3 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1273,6 +1273,24 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { seat_set_workspace_focus(seat, node); } if (server.session_lock.lock) { + struct sway_output *output = NULL; + if (node != NULL) { + switch (node->type) { + case N_OUTPUT: + output = node->sway_output; + break; + case N_WORKSPACE: + output = node->sway_workspace->output; + break; + default: + break; + } + } + if (output != NULL) { + sway_session_lock_focus_output(server.session_lock.lock, output); + return; + } + // Fallback to the previously focused lock surface seat_set_focus_surface(seat, server.session_lock.lock->focused, false); } } diff --git a/sway/lock.c b/sway/lock.c index c8975c747..a75c1e7e2 100644 --- a/sway/lock.c +++ b/sway/lock.c @@ -59,6 +59,23 @@ static void refocus_output(struct sway_session_lock_output *output) { } } +void sway_session_lock_focus_output(struct sway_session_lock *lock, + struct sway_output *output) { + // Try focusing the lock surface on the provided output + struct sway_session_lock_output *candidate; + wl_list_for_each(candidate, &lock->outputs, link) { + if (candidate->output != output || !candidate->surface) { + continue; + } + + if (candidate->surface->surface->mapped) { + // Set the focus for all seats + focus_surface(lock, candidate->surface->surface); + break; + } + } +} + static void handle_surface_map(struct wl_listener *listener, void *data) { struct sway_session_lock_output *surf = wl_container_of(listener, surf, surface_map); if (surf->lock->focused == NULL) { From 1737a58b01922584863b0eaa9c4735fa96527619 Mon Sep 17 00:00:00 2001 From: Erik Reider <35975961+ErikReider@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:27:04 +0200 Subject: [PATCH 2/2] Initially focus the lock surface that has the current output focus --- sway/lock.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sway/lock.c b/sway/lock.c index a75c1e7e2..2b9b74b03 100644 --- a/sway/lock.c +++ b/sway/lock.c @@ -8,6 +8,7 @@ #include "sway/layers.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/tree/workspace.h" #include "sway/lock.h" struct sway_session_lock_output { @@ -78,7 +79,15 @@ void sway_session_lock_focus_output(struct sway_session_lock *lock, static void handle_surface_map(struct wl_listener *listener, void *data) { struct sway_session_lock_output *surf = wl_container_of(listener, surf, surface_map); - if (surf->lock->focused == NULL) { + + struct sway_seat *seat = input_manager_current_seat(); + struct sway_workspace *focused_ws = seat_get_focused_workspace(seat); + struct sway_output *focused_output = NULL; + if (focused_ws != NULL) { + focused_output = focused_ws->output; + } + + if (surf->lock->focused == NULL || focused_output == surf->output) { focus_surface(surf->lock, surf->surface->surface); } cursor_rebase_all();