layer: improve keyboard-interactivity

- Process layer-shell keyboard interactivity in the map and commit
  handlers only, rather than in layers_arrange(). This allows handling of
  the layer-surface that emitted the event rather than iterating over all
  surfaces in the output layer-tree, and therefore avoids having to guess
  which surface should have keyboard preference (and it might not be the
  last one added to the list which was the assumption previously).

- Prevent seat_focus_surface() from setting keyboard focus if a layer-shell
  surface with exclusive keyboard-interactivity has the focus.

- Set cursor_context type for layer-surfaces without node-descriptors
  in order to set keyboard focus correctly in cursor_button_press().

Tested satisfactorily with xfce4-panel and gtk-layer-demo.

Fixes #725 and #704
This commit is contained in:
Johan Malm 2023-01-28 22:34:27 +00:00 committed by Johan Malm
parent 4dc99e2f38
commit 6f3043b08d
3 changed files with 72 additions and 35 deletions

View file

@ -440,8 +440,8 @@ seat_reconfigure(struct server *server)
}
}
void
seat_focus_surface(struct seat *seat, struct wlr_surface *surface)
static void
seat_focus(struct seat *seat, struct wlr_surface *surface)
{
if (!surface) {
wlr_seat_keyboard_notify_clear_focus(seat->seat);
@ -469,6 +469,17 @@ seat_focus_surface(struct seat *seat, struct wlr_surface *surface)
constrain_cursor(server, constraint);
}
void
seat_focus_surface(struct seat *seat, struct wlr_surface *surface)
{
/* Respect layer-shell exlusive keyboard-interactivity. */
if (seat->focused_layer && seat->focused_layer->current.keyboard_interactive
== ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
return;
}
seat_focus(seat, surface);
}
void
seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer)
{
@ -477,7 +488,7 @@ seat_set_focus_layer(struct seat *seat, struct wlr_layer_surface_v1 *layer)
desktop_focus_topmost_mapped_view(seat->server);
return;
}
seat_focus_surface(seat, layer->surface);
seat_focus(seat, layer->surface);
if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
seat->focused_layer = layer;
}