commit 0356a020c1c14b4f9e9c3583d6a87dd7764714a2
parent d6425c527a0b0af26e763f2a1201df7c7e24cbc1
Author: Lars-Ragnar A. Haugen <lars-ragnar.antell.haugen@dig.oslo.kommune.no>
Date: Thu, 26 Feb 2026 16:34:37 +0100
layer-shell: handle popup reposition for unconstraining
Layer shell popups were missing a handler for the xdg_popup reposition
event. When a client (e.g. GTK4) creates a popup and then sends a
reposition request, wlroots resets the scheduled geometry back to the
positioner's original value. Without a reposition handler, the
unconstrained geometry computed on the initial commit was lost, causing
popups such as tooltips to render outside the screen viewport.
This was most visible with GTK4 layer shell apps (e.g. taskbars) where
tooltips would appear below the bottom edge of the screen instead of
being flipped/slid into the visible area.
Also switch the destroy listener from wlr_popup->base->events.destroy
to wlr_popup->events.destroy so that cleanup runs before wlroots
asserts that all popup signal listeners have been removed.
Fixes #8518
Diffstat:
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/include/sway/layers.h b/include/sway/layers.h
@@ -33,6 +33,7 @@ struct sway_layer_popup {
struct wl_listener destroy;
struct wl_listener new_popup;
struct wl_listener commit;
+ struct wl_listener reposition;
};
struct sway_output;
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c
@@ -321,6 +321,7 @@ static void popup_handle_destroy(struct wl_listener *listener, void *data) {
wl_list_remove(&popup->destroy.link);
wl_list_remove(&popup->new_popup.link);
wl_list_remove(&popup->commit.link);
+ wl_list_remove(&popup->reposition.link);
free(popup);
}
@@ -356,6 +357,11 @@ static void popup_handle_commit(struct wl_listener *listener, void *data) {
}
}
+static void popup_handle_reposition(struct wl_listener *listener, void *data) {
+ struct sway_layer_popup *popup = wl_container_of(listener, popup, reposition);
+ popup_unconstrain(popup);
+}
+
static void popup_handle_new_popup(struct wl_listener *listener, void *data);
static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
@@ -376,11 +382,13 @@ static struct sway_layer_popup *create_popup(struct wlr_xdg_popup *wlr_popup,
}
popup->destroy.notify = popup_handle_destroy;
- wl_signal_add(&wlr_popup->base->events.destroy, &popup->destroy);
+ wl_signal_add(&wlr_popup->events.destroy, &popup->destroy);
popup->new_popup.notify = popup_handle_new_popup;
wl_signal_add(&wlr_popup->base->events.new_popup, &popup->new_popup);
popup->commit.notify = popup_handle_commit;
wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
+ popup->reposition.notify = popup_handle_reposition;
+ wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
return popup;
}