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 {