aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Daniel De Graaf <code@danieldg.net>2022-04-30 00:46:53 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2022-10-28 19:41:24 +0200
commit8aa89dc27736fc4940f3811ef15bb3135e629a8c (patch)
tree2ca6878657ed22e6150f478ace9651b3d61e5ebe /sway/input/seat.c
parentRework session lock keyboard focus handling (diff)
downloadsway-8aa89dc27736fc4940f3811ef15bb3135e629a8c.tar.gz
sway-8aa89dc27736fc4940f3811ef15bb3135e629a8c.tar.zst
sway-8aa89dc27736fc4940f3811ef15bb3135e629a8c.zip
Fix focus tracking when session lock is active
Remove the incorrect attempt to block focus changes when an input grab is present and replace it with the same logic used for layer_shell-based screen lockers: restore the focus after changing it. This fixes a use-after-free of seat->workspace if outputs are destroyed while a screen lock is enabled.
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index a7408287..43b20779 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -1134,15 +1134,7 @@ void seat_set_raw_focus(struct sway_seat *seat, struct sway_node *node) {
1134 } 1134 }
1135} 1135}
1136 1136
1137void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { 1137static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *node) {
1138 if (seat->focused_layer) {
1139 struct wlr_layer_surface_v1 *layer = seat->focused_layer;
1140 seat_set_focus_layer(seat, NULL);
1141 seat_set_focus(seat, node);
1142 seat_set_focus_layer(seat, layer);
1143 return;
1144 }
1145
1146 struct sway_node *last_focus = seat_get_focus(seat); 1138 struct sway_node *last_focus = seat_get_focus(seat);
1147 if (last_focus == node) { 1139 if (last_focus == node) {
1148 return; 1140 return;
@@ -1176,11 +1168,6 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1176 return; 1168 return;
1177 } 1169 }
1178 1170
1179 // Deny setting focus when an input grab or lockscreen is active
1180 if (container && container->view && !seat_is_input_allowed(seat, container->view->surface)) {
1181 return;
1182 }
1183
1184 struct sway_output *new_output = 1171 struct sway_output *new_output =
1185 new_workspace ? new_workspace->output : NULL; 1172 new_workspace ? new_workspace->output : NULL;
1186 1173
@@ -1280,6 +1267,20 @@ void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1280 } 1267 }
1281} 1268}
1282 1269
1270void seat_set_focus(struct sway_seat *seat, struct sway_node *node) {
1271 if (seat->focused_layer) {
1272 struct wlr_layer_surface_v1 *layer = seat->focused_layer;
1273 seat_set_focus_layer(seat, NULL);
1274 seat_set_workspace_focus(seat, node);
1275 seat_set_focus_layer(seat, layer);
1276 } else {
1277 seat_set_workspace_focus(seat, node);
1278 }
1279 if (server.session_lock.locked) {
1280 seat_set_focus_surface(seat, server.session_lock.focused, false);
1281 }
1282}
1283
1283void seat_set_focus_container(struct sway_seat *seat, 1284void seat_set_focus_container(struct sway_seat *seat,
1284 struct sway_container *con) { 1285 struct sway_container *con) {
1285 seat_set_focus(seat, con ? &con->node : NULL); 1286 seat_set_focus(seat, con ? &con->node : NULL);