aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/wlr/types/wlr_xdg_shell.h8
-rw-r--r--types/xdg_shell/wlr_xdg_surface.c32
2 files changed, 40 insertions, 0 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h
index 04addfe1..a519ed8b 100644
--- a/include/wlr/types/wlr_xdg_shell.h
+++ b/include/wlr/types/wlr_xdg_shell.h
@@ -393,6 +393,14 @@ void wlr_xdg_surface_for_each_surface(struct wlr_xdg_surface *surface,
wlr_surface_iterator_func_t iterator, void *user_data);
/**
+ * Call `iterator` on each popup's surface and popup's subsurface in the
+ * xdg-surface tree, with the surfaces's position relative to the root
+ * xdg-surface. The function is called from root to leaves (in rendering order).
+ */
+void wlr_xdg_surface_for_each_popup_surface(struct wlr_xdg_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data);
+
+/**
* Schedule a surface configuration. This should only be called by protocols
* extending the shell.
*/
diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c
index b65490d0..6333119f 100644
--- a/types/xdg_shell/wlr_xdg_surface.c
+++ b/types/xdg_shell/wlr_xdg_surface.c
@@ -662,11 +662,43 @@ static void xdg_surface_for_each_popup(struct wlr_xdg_surface *surface,
}
}
+static void xdg_surface_for_each_popup_surface(struct wlr_xdg_surface *surface,
+ int x, int y, wlr_surface_iterator_func_t iterator, void *user_data) {
+ struct wlr_xdg_popup *popup_state;
+ wl_list_for_each(popup_state, &surface->popups, link) {
+ struct wlr_xdg_surface *popup = popup_state->base;
+ if (!popup->configured) {
+ continue;
+ }
+
+ double popup_sx, popup_sy;
+ xdg_popup_get_position(popup_state, &popup_sx, &popup_sy);
+
+ struct xdg_surface_iterator_data data = {
+ .user_iterator = iterator,
+ .user_data = user_data,
+ .x = x + popup_sx, .y = y + popup_sy,
+ };
+ wlr_surface_for_each_surface(popup->surface, xdg_surface_iterator,
+ &data);
+
+ xdg_surface_for_each_popup_surface(popup,
+ x + popup_sx,
+ y + popup_sy,
+ iterator, user_data);
+ }
+}
+
void wlr_xdg_surface_for_each_surface(struct wlr_xdg_surface *surface,
wlr_surface_iterator_func_t iterator, void *user_data) {
xdg_surface_for_each_surface(surface, 0, 0, iterator, user_data);
}
+void wlr_xdg_surface_for_each_popup_surface(struct wlr_xdg_surface *surface,
+ wlr_surface_iterator_func_t iterator, void *user_data) {
+ xdg_surface_for_each_popup_surface(surface, 0, 0, iterator, user_data);
+}
+
void wlr_xdg_surface_for_each_popup(struct wlr_xdg_surface *surface,
wlr_surface_iterator_func_t iterator, void *user_data) {
xdg_surface_for_each_popup(surface, 0, 0, iterator, user_data);