aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2021-01-07 15:04:08 +0100
committerSimon Ser <contact@emersion.fr>2021-01-08 12:05:13 +0100
commit8f63557ed7695a8ae5a4acb85a2693dc36be85bb (patch)
treed9d7eaf4fbd029c964459a61fa94bc5cfc050f63
parentc5c5ab97249861ae1d17cad382e001646f27486d (diff)
xdg shell: add wlr_xdg_surface_popup_surface_at()
This function will allow compositors to implement input handling in a way consistent with rendering more easily. Calling wlr_xdg_surface_surface_at() and checking if the result is a wlr_xdg_popup is flawed as there may be subsurfaces in the popup tree.
-rw-r--r--include/wlr/types/wlr_xdg_shell.h9
-rw-r--r--types/xdg_shell/wlr_xdg_surface.c13
2 files changed, 21 insertions, 1 deletions
diff --git a/include/wlr/types/wlr_xdg_shell.h b/include/wlr/types/wlr_xdg_shell.h
index a519ed8b..102b26cf 100644
--- a/include/wlr/types/wlr_xdg_shell.h
+++ b/include/wlr/types/wlr_xdg_shell.h
@@ -369,6 +369,15 @@ struct wlr_surface *wlr_xdg_surface_surface_at(
struct wlr_xdg_surface *surface, double sx, double sy,
double *sub_x, double *sub_y);
+/**
+ * Find a surface within this xdg-surface's popup tree at the given
+ * surface-local coordinates. Returns the surface and coordinates in the leaf
+ * surface coordinate system or NULL if no surface is found at that location.
+ */
+struct wlr_surface *wlr_xdg_surface_popup_surface_at(
+ struct wlr_xdg_surface *surface, double sx, double sy,
+ double *sub_x, double *sub_y);
+
bool wlr_surface_is_xdg_surface(struct wlr_surface *surface);
struct wlr_xdg_surface *wlr_xdg_surface_from_wlr_surface(
diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c
index 6333119f..d4e0c6f0 100644
--- a/types/xdg_shell/wlr_xdg_surface.c
+++ b/types/xdg_shell/wlr_xdg_surface.c
@@ -583,6 +583,17 @@ static void xdg_popup_get_position(struct wlr_xdg_popup *popup,
struct wlr_surface *wlr_xdg_surface_surface_at(
struct wlr_xdg_surface *surface, double sx, double sy,
double *sub_x, double *sub_y) {
+ struct wlr_surface *sub = wlr_xdg_surface_popup_surface_at(surface, sx, sy,
+ sub_x, sub_y);
+ if (sub != NULL) {
+ return sub;
+ }
+ return wlr_surface_surface_at(surface->surface, sx, sy, sub_x, sub_y);
+}
+
+struct wlr_surface *wlr_xdg_surface_popup_surface_at(
+ struct wlr_xdg_surface *surface, double sx, double sy,
+ double *sub_x, double *sub_y) {
struct wlr_xdg_popup *popup_state;
wl_list_for_each(popup_state, &surface->popups, link) {
struct wlr_xdg_surface *popup = popup_state->base;
@@ -599,7 +610,7 @@ struct wlr_surface *wlr_xdg_surface_surface_at(
}
}
- return wlr_surface_surface_at(surface->surface, sx, sy, sub_x, sub_y);
+ return NULL;
}
struct xdg_surface_iterator_data {