aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2021-01-07 14:41:24 +0100
committerSimon Ser <contact@emersion.fr>2021-01-08 10:33:16 +0100
commitc5c5ab97249861ae1d17cad382e001646f27486d (patch)
tree1f8aa5ade5ad6f4924ee765c07aa6d10d53bfb43
parent129e02b57d95c979ec230f115b510559102606cf (diff)
xdg shell: add wlr_xdg_surface_for_each_popup_surface()
When rendering, it is necessary to iterate the subsurfaces as well, so add a function that makes this easy.
-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);