diff options
Diffstat (limited to 'sway/desktop/layer_shell.c')
-rw-r--r-- | sway/desktop/layer_shell.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 50aa6938..d990d92a 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -17,6 +17,39 @@ | |||
17 | #include "sway/tree/arrange.h" | 17 | #include "sway/tree/arrange.h" |
18 | #include "sway/tree/workspace.h" | 18 | #include "sway/tree/workspace.h" |
19 | 19 | ||
20 | struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface( | ||
21 | struct wlr_surface *surface) { | ||
22 | struct wlr_layer_surface_v1 *layer; | ||
23 | do { | ||
24 | if (!surface) { | ||
25 | return NULL; | ||
26 | } | ||
27 | // Topmost layer surface | ||
28 | if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) { | ||
29 | return layer; | ||
30 | } | ||
31 | // Layer subsurface | ||
32 | if (wlr_subsurface_try_from_wlr_surface(surface)) { | ||
33 | surface = wlr_surface_get_root_surface(surface); | ||
34 | continue; | ||
35 | } | ||
36 | |||
37 | // Layer surface popup | ||
38 | struct wlr_xdg_surface * xdg_popup = NULL; | ||
39 | if ((xdg_popup = wlr_xdg_surface_try_from_wlr_surface(surface)) && | ||
40 | xdg_popup->role == WLR_XDG_SURFACE_ROLE_POPUP) { | ||
41 | if (!xdg_popup->popup->parent) { | ||
42 | return NULL; | ||
43 | } | ||
44 | surface = wlr_surface_get_root_surface(xdg_popup->popup->parent); | ||
45 | continue; | ||
46 | } | ||
47 | |||
48 | // Return early if the surface is not a layer/xdg_popup/sub surface | ||
49 | return NULL; | ||
50 | } while (true); | ||
51 | } | ||
52 | |||
20 | static void apply_exclusive(struct wlr_box *usable_area, | 53 | static void apply_exclusive(struct wlr_box *usable_area, |
21 | uint32_t anchor, int32_t exclusive, | 54 | uint32_t anchor, int32_t exclusive, |
22 | int32_t margin_top, int32_t margin_right, | 55 | int32_t margin_top, int32_t margin_right, |
@@ -218,7 +251,8 @@ void arrange_layers(struct sway_output *output) { | |||
218 | for (size_t i = 0; i < nlayers; ++i) { | 251 | for (size_t i = 0; i < nlayers; ++i) { |
219 | wl_list_for_each_reverse(layer, | 252 | wl_list_for_each_reverse(layer, |
220 | &output->layers[layers_above_shell[i]], link) { | 253 | &output->layers[layers_above_shell[i]], link) { |
221 | if (layer->layer_surface->current.keyboard_interactive && | 254 | if (layer->layer_surface->current.keyboard_interactive |
255 | == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE && | ||
222 | layer->layer_surface->surface->mapped) { | 256 | layer->layer_surface->surface->mapped) { |
223 | topmost = layer; | 257 | topmost = layer; |
224 | break; | 258 | break; |
@@ -231,10 +265,12 @@ void arrange_layers(struct sway_output *output) { | |||
231 | 265 | ||
232 | struct sway_seat *seat; | 266 | struct sway_seat *seat; |
233 | wl_list_for_each(seat, &server.input->seats, link) { | 267 | wl_list_for_each(seat, &server.input->seats, link) { |
268 | seat->has_exclusive_layer = false; | ||
234 | if (topmost != NULL) { | 269 | if (topmost != NULL) { |
235 | seat_set_focus_layer(seat, topmost->layer_surface); | 270 | seat_set_focus_layer(seat, topmost->layer_surface); |
236 | } else if (seat->focused_layer && | 271 | } else if (seat->focused_layer && |
237 | !seat->focused_layer->current.keyboard_interactive) { | 272 | seat->focused_layer->current.keyboard_interactive |
273 | != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) { | ||
238 | seat_set_focus_layer(seat, NULL); | 274 | seat_set_focus_layer(seat, NULL); |
239 | } | 275 | } |
240 | } | 276 | } |