aboutsummaryrefslogtreecommitdiff
path: root/sway/desktop
diff options
context:
space:
mode:
Diffstat (limited to 'sway/desktop')
-rw-r--r--sway/desktop/layer_shell.c40
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 @@
#include "sway/tree/arrange.h"
#include "sway/tree/workspace.h"
+struct wlr_layer_surface_v1 *toplevel_layer_surface_from_surface(
+ struct wlr_surface *surface) {
+ struct wlr_layer_surface_v1 *layer;
+ do {
+ if (!surface) {
+ return NULL;
+ }
+ // Topmost layer surface
+ if ((layer = wlr_layer_surface_v1_try_from_wlr_surface(surface))) {
+ return layer;
+ }
+ // Layer subsurface
+ if (wlr_subsurface_try_from_wlr_surface(surface)) {
+ surface = wlr_surface_get_root_surface(surface);
+ continue;
+ }
+
+ // Layer surface popup
+ struct wlr_xdg_surface * xdg_popup = NULL;
+ if ((xdg_popup = wlr_xdg_surface_try_from_wlr_surface(surface)) &&
+ xdg_popup->role == WLR_XDG_SURFACE_ROLE_POPUP) {
+ if (!xdg_popup->popup->parent) {
+ return NULL;
+ }
+ surface = wlr_surface_get_root_surface(xdg_popup->popup->parent);
+ continue;
+ }
+
+ // Return early if the surface is not a layer/xdg_popup/sub surface
+ return NULL;
+ } while (true);
+}
+
static void apply_exclusive(struct wlr_box *usable_area,
uint32_t anchor, int32_t exclusive,
int32_t margin_top, int32_t margin_right,
@@ -218,7 +251,8 @@ void arrange_layers(struct sway_output *output) {
for (size_t i = 0; i < nlayers; ++i) {
wl_list_for_each_reverse(layer,
&output->layers[layers_above_shell[i]], link) {
- if (layer->layer_surface->current.keyboard_interactive &&
+ if (layer->layer_surface->current.keyboard_interactive
+ == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE &&
layer->layer_surface->surface->mapped) {
topmost = layer;
break;
@@ -231,10 +265,12 @@ void arrange_layers(struct sway_output *output) {
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) {
+ seat->focused_layer->current.keyboard_interactive
+ != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) {
seat_set_focus_layer(seat, NULL);
}
}