diff options
author | Erik Reider <35975961+ErikReider@users.noreply.github.com> | 2023-06-05 15:31:16 +0200 |
---|---|---|
committer | Kenny Levinsen <kl@kl.wtf> | 2023-06-06 09:07:05 +0200 |
commit | 913a7679cbde98df0722b326d8c3cfc0f0576f6d (patch) | |
tree | 752fea000515bcd93a40fc175dbbace5221ee9c4 /sway/input | |
parent | 7ab8cb2ee6f11693987d9f24abec708144807b53 (diff) |
Add support for wlr-layer-shell ON_DEMAND keyboard interactivity
This allows for layer shell surfaces to receive focus while the surface is explicitly focused, i.e allowing
text fields to receive keyboard input just like a regular surface.
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/seat.c | 20 | ||||
-rw-r--r-- | sway/input/seatop_default.c | 24 |
2 files changed, 35 insertions, 9 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 5795f40f..fdd21057 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1295,11 +1295,15 @@ static void seat_set_workspace_focus(struct sway_seat *seat, struct sway_node *n } void seat_set_focus(struct sway_seat *seat, struct sway_node *node) { - if (seat->focused_layer) { + // Prevents the layer from losing focus if it has keyboard exclusivity + if (seat->has_exclusive_layer) { struct wlr_layer_surface_v1 *layer = seat->focused_layer; seat_set_focus_layer(seat, NULL); seat_set_workspace_focus(seat, node); seat_set_focus_layer(seat, layer); + } else if (seat->focused_layer) { + seat_set_focus_layer(seat, NULL); + seat_set_workspace_focus(seat, node); } else { seat_set_workspace_focus(seat, node); } @@ -1347,14 +1351,20 @@ void seat_set_focus_layer(struct sway_seat *seat, seat_set_focus(seat, previous); } return; - } else if (!layer || seat->focused_layer == layer) { + } else if (!layer) { return; } assert(layer->surface->mapped); - seat_set_focus_surface(seat, layer->surface, true); - if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) { - seat->focused_layer = layer; + if (layer->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP && + layer->current.keyboard_interactive + == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) { + seat->has_exclusive_layer = true; + } + if (seat->focused_layer == layer) { + return; } + seat_set_focus_surface(seat, layer->surface, true); + seat->focused_layer = layer; } void seat_set_exclusive_client(struct sway_seat *seat, diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index 5a55c186..f4c63808 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c @@ -2,6 +2,7 @@ #include <float.h> #include <libevdev/libevdev.h> #include <wlr/types/wlr_cursor.h> +#include <wlr/types/wlr_subcompositor.h> #include <wlr/types/wlr_tablet_v2.h> #include <wlr/types/wlr_xcursor_manager.h> #include "gesture.h" @@ -9,6 +10,7 @@ #include "sway/input/cursor.h" #include "sway/input/seat.h" #include "sway/input/tablet.h" +#include "sway/layers.h" #include "sway/output.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" @@ -365,10 +367,9 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec, return; } - // Handle clicking a layer surface - struct wlr_layer_surface_v1 *layer; - if (surface && - (layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) { + // Handle clicking a layer surface and its popups/subsurfaces + struct wlr_layer_surface_v1 *layer = NULL; + if ((layer = toplevel_layer_surface_from_surface(surface))) { if (layer->current.keyboard_interactive) { seat_set_focus_layer(seat, layer); transaction_commit_dirty(); @@ -544,6 +545,21 @@ static void check_focus_follows_mouse(struct sway_seat *seat, if (wlr_output == NULL) { return; } + + struct wlr_surface *surface = NULL; + double sx, sy; + node_at_coords(seat, seat->cursor->cursor->x, seat->cursor->cursor->y, + &surface, &sx, &sy); + + // Focus topmost layer surface + struct wlr_layer_surface_v1 *layer = NULL; + if ((layer = toplevel_layer_surface_from_surface(surface)) && + layer->current.keyboard_interactive) { + seat_set_focus_layer(seat, layer); + transaction_commit_dirty(); + return; + } + struct sway_output *hovered_output = wlr_output->data; if (focus && hovered_output != node_get_output(focus)) { struct sway_workspace *ws = output_get_active_workspace(hovered_output); |