aboutsummaryrefslogtreecommitdiffstats
path: root/sway/lock.c
diff options
context:
space:
mode:
authorLibravatar Daniel De Graaf <code@danieldg.net>2022-04-29 23:40:16 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2022-10-28 19:41:24 +0200
commit8f7bb145b72209724f05b0182dee33c0e47d2357 (patch)
treef2eee1187e0bdfc562130294de8dde1021e84642 /sway/lock.c
parentFix keymap being NULL and segfaulting on dev add (diff)
downloadsway-8f7bb145b72209724f05b0182dee33c0e47d2357.tar.gz
sway-8f7bb145b72209724f05b0182dee33c0e47d2357.tar.zst
sway-8f7bb145b72209724f05b0182dee33c0e47d2357.zip
Rework session lock keyboard focus handling
When removing outputs, it is possible to end up in a situation where none of the session lock client's surfaces have keyboard focus, resulting in it not receiving keyboard events. Track the focused surface and update it as needed on surface destroy.
Diffstat (limited to 'sway/lock.c')
-rw-r--r--sway/lock.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/sway/lock.c b/sway/lock.c
index 04f80079..3c7c06cf 100644
--- a/sway/lock.c
+++ b/sway/lock.c
@@ -17,9 +17,20 @@ struct sway_session_lock_surface {
17 struct wl_listener output_commit; 17 struct wl_listener output_commit;
18}; 18};
19 19
20static void set_lock_focused_surface(struct wlr_surface *focused) {
21 server.session_lock.focused = focused;
22
23 struct sway_seat *seat;
24 wl_list_for_each(seat, &server.input->seats, link) {
25 seat_set_focus_surface(seat, focused, false);
26 }
27}
28
20static void handle_surface_map(struct wl_listener *listener, void *data) { 29static void handle_surface_map(struct wl_listener *listener, void *data) {
21 struct sway_session_lock_surface *surf = wl_container_of(listener, surf, map); 30 struct sway_session_lock_surface *surf = wl_container_of(listener, surf, map);
22 sway_force_focus(surf->surface); 31 if (server.session_lock.focused == NULL) {
32 set_lock_focused_surface(surf->surface);
33 }
23 output_damage_whole(surf->output); 34 output_damage_whole(surf->output);
24} 35}
25 36
@@ -48,6 +59,21 @@ static void handle_output_commit(struct wl_listener *listener, void *data) {
48 59
49static void handle_surface_destroy(struct wl_listener *listener, void *data) { 60static void handle_surface_destroy(struct wl_listener *listener, void *data) {
50 struct sway_session_lock_surface *surf = wl_container_of(listener, surf, destroy); 61 struct sway_session_lock_surface *surf = wl_container_of(listener, surf, destroy);
62
63 // Move the seat focus to another surface if one is available
64 if (server.session_lock.focused == surf->surface) {
65 struct wlr_surface *next_focus = NULL;
66
67 struct wlr_session_lock_surface_v1 *other;
68 wl_list_for_each(other, &server.session_lock.lock->surfaces, link) {
69 if (other != surf->lock_surface && other->mapped) {
70 next_focus = other->surface;
71 break;
72 }
73 }
74 set_lock_focused_surface(next_focus);
75 }
76
51 wl_list_remove(&surf->map.link); 77 wl_list_remove(&surf->map.link);
52 wl_list_remove(&surf->destroy.link); 78 wl_list_remove(&surf->destroy.link);
53 wl_list_remove(&surf->surface_commit.link); 79 wl_list_remove(&surf->surface_commit.link);
@@ -88,6 +114,7 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
88 sway_log(SWAY_DEBUG, "session unlocked"); 114 sway_log(SWAY_DEBUG, "session unlocked");
89 server.session_lock.locked = false; 115 server.session_lock.locked = false;
90 server.session_lock.lock = NULL; 116 server.session_lock.lock = NULL;
117 server.session_lock.focused = NULL;
91 118
92 wl_list_remove(&server.session_lock.lock_new_surface.link); 119 wl_list_remove(&server.session_lock.lock_new_surface.link);
93 wl_list_remove(&server.session_lock.lock_unlock.link); 120 wl_list_remove(&server.session_lock.lock_unlock.link);
@@ -115,6 +142,7 @@ static void handle_unlock(struct wl_listener *listener, void *data) {
115static void handle_abandon(struct wl_listener *listener, void *data) { 142static void handle_abandon(struct wl_listener *listener, void *data) {
116 sway_log(SWAY_INFO, "session lock abandoned"); 143 sway_log(SWAY_INFO, "session lock abandoned");
117 server.session_lock.lock = NULL; 144 server.session_lock.lock = NULL;
145 server.session_lock.focused = NULL;
118 146
119 wl_list_remove(&server.session_lock.lock_new_surface.link); 147 wl_list_remove(&server.session_lock.lock_new_surface.link);
120 wl_list_remove(&server.session_lock.lock_unlock.link); 148 wl_list_remove(&server.session_lock.lock_unlock.link);