summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFurkan Sahin <furkan-dev@proton.me>2024-07-20 22:34:01 +0000
committerFurkan Sahin <furkan-dev@proton.me>2024-07-20 22:34:01 +0000
commit61e4eb34fe6df0ac6b4a2fee5ba02c76ce1ec9b4 (patch)
tree900a53a46730212399b0fb0aed4325b31538696e
parent0b6f45a0657a0dab6d401c3c070741a5c98d20bc (diff)
layer-shell: Restore interactive layer focus code
Commit f2f4af868bfa ("scene_graph: Port layer_shell") accidentally removed code in `arrange_layers` to handle focus on layer shell surfaces with keyboard interactivity. Due to this, layer shell surfaces requesting exclusive keyboard interactivity may not get automatically focused, and layer shell surfaces giving up exclusive keyboard interactivity can remain focused. Add the previous code back to fix the problem. Note the non-rename change included in 3e58196b0a07 ("desktop: Rename layers to shell_layers") is not included as it also seems accidental. Fixes: #7936 (cherry picked from commit 4d4c88f0a73f6ee3da1c99355f04362ef2ad68c9)
-rw-r--r--sway/desktop/layer_shell.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
index 6221b7b9..b136a24e 100644
--- a/sway/desktop/layer_shell.c
+++ b/sway/desktop/layer_shell.c
@@ -90,6 +90,43 @@ void arrange_layers(struct sway_output *output) {
} else {
arrange_popups(root->layers.popup);
}
+
+ // Find topmost keyboard interactive layer, if such a layer exists
+ struct wlr_scene_tree *layers_above_shell[] = {
+ output->layers.shell_overlay,
+ output->layers.shell_top,
+ };
+ size_t nlayers = sizeof(layers_above_shell) / sizeof(layers_above_shell[0]);
+ struct wlr_scene_node *node;
+ struct sway_layer_surface *topmost = NULL;
+ for (size_t i = 0; i < nlayers; ++i) {
+ wl_list_for_each_reverse(node,
+ &layers_above_shell[i]->children, link) {
+ struct sway_layer_surface *surface = scene_descriptor_try_get(node,
+ SWAY_SCENE_DESC_LAYER_SHELL);
+ if (surface && surface->layer_surface->current.keyboard_interactive
+ == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE &&
+ surface->layer_surface->surface->mapped) {
+ topmost = surface;
+ break;
+ }
+ }
+ if (topmost != NULL) {
+ break;
+ }
+ }
+
+ struct sway_seat *seat;
+ wl_list_for_each(seat, &server.input->seats, link) {
+ seat->has_exclusive_layer = false;
+ if (topmost != NULL) {
+ seat_set_focus_layer(seat, topmost->layer_surface);
+ } else if (seat->focused_layer &&
+ seat->focused_layer->current.keyboard_interactive
+ != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
+ seat_set_focus_layer(seat, NULL);
+ }
+ }
}
static struct wlr_scene_tree *sway_layer_get_scene(struct sway_output *output,