From 7f5967234c1bcd4a93252d8606bf0f5a647c7dfa Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 5 Feb 2019 19:27:23 +0100 Subject: [PATCH] xdg-shell: destroy child popups on unmap It doesn't make sense to keep popups opened when unmapped. We also need to do so in wlr_xdg_popup_destroy so that popups are destroyed in the correct order. --- include/types/wlr_xdg_shell.h | 1 - types/xdg_shell/wlr_xdg_popup.c | 16 +++++----------- types/xdg_shell/wlr_xdg_surface.c | 19 ++++++++++++------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/types/wlr_xdg_shell.h b/include/types/wlr_xdg_shell.h index 08a691bd..93058530 100644 --- a/include/types/wlr_xdg_shell.h +++ b/include/types/wlr_xdg_shell.h @@ -33,7 +33,6 @@ void create_xdg_popup(struct wlr_xdg_surface *xdg_surface, void handle_xdg_surface_popup_committed(struct wlr_xdg_surface *surface); struct wlr_xdg_popup_grab *get_xdg_shell_popup_grab_from_seat( struct wlr_xdg_shell *shell, struct wlr_seat *seat); -void destroy_xdg_popup(struct wlr_xdg_surface *surface); void create_xdg_toplevel(struct wlr_xdg_surface *xdg_surface, uint32_t id); diff --git a/types/xdg_shell/wlr_xdg_popup.c b/types/xdg_shell/wlr_xdg_popup.c index b27a629e..4e4b9c5b 100644 --- a/types/xdg_shell/wlr_xdg_popup.c +++ b/types/xdg_shell/wlr_xdg_popup.c @@ -210,9 +210,12 @@ static const struct xdg_popup_interface xdg_popup_implementation = { }; static void xdg_popup_handle_resource_destroy(struct wl_resource *resource) { - struct wlr_xdg_surface *surface = + struct wlr_xdg_surface *xdg_surface = wlr_xdg_surface_from_popup_resource(resource); - destroy_xdg_popup(surface); + if (xdg_surface == NULL) { + return; + } + wlr_xdg_popup_destroy(xdg_surface); } const struct wlr_surface_role xdg_popup_surface_role = { @@ -281,15 +284,6 @@ void create_xdg_popup(struct wlr_xdg_surface *xdg_surface, } } -void destroy_xdg_popup(struct wlr_xdg_surface *xdg_surface) { - if (xdg_surface == NULL) { - return; - } - assert(xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP || - xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE); - reset_xdg_surface(xdg_surface); -} - void wlr_xdg_popup_get_anchor_point(struct wlr_xdg_popup *popup, int *root_sx, int *root_sy) { struct wlr_box rect = popup->positioner.anchor_rect; diff --git a/types/xdg_shell/wlr_xdg_surface.c b/types/xdg_shell/wlr_xdg_surface.c index db3fc29a..ada5b419 100644 --- a/types/xdg_shell/wlr_xdg_surface.c +++ b/types/xdg_shell/wlr_xdg_surface.c @@ -29,6 +29,11 @@ static void xdg_surface_configure_destroy( void unmap_xdg_surface(struct wlr_xdg_surface *surface) { assert(surface->role != WLR_XDG_SURFACE_ROLE_NONE); + struct wlr_xdg_popup *popup, *popup_tmp; + wl_list_for_each_safe(popup, popup_tmp, &surface->popups, link) { + wlr_xdg_popup_destroy(popup->base); + } + // TODO: probably need to ungrab before this event if (surface->mapped) { wlr_signal_emit_safe(&surface->events.unmap, surface); @@ -477,12 +482,6 @@ void reset_xdg_surface(struct wlr_xdg_surface *xdg_surface) { void destroy_xdg_surface(struct wlr_xdg_surface *surface) { reset_xdg_surface(surface); - struct wlr_xdg_popup *popup_state, *next; - wl_list_for_each_safe(popup_state, next, &surface->popups, link) { - xdg_popup_send_popup_done(popup_state->resource); - destroy_xdg_popup(popup_state->base); - } - wl_resource_set_user_data(surface->resource, NULL); surface->surface->role_data = NULL; @@ -529,9 +528,15 @@ void wlr_xdg_popup_destroy(struct wlr_xdg_surface *surface) { } assert(surface->popup); assert(surface->role == WLR_XDG_SURFACE_ROLE_POPUP); + + struct wlr_xdg_popup *popup, *popup_tmp; + wl_list_for_each_safe(popup, popup_tmp, &surface->popups, link) { + wlr_xdg_popup_destroy(popup->base); + } + xdg_popup_send_popup_done(surface->popup->resource); wl_resource_set_user_data(surface->popup->resource, NULL); - destroy_xdg_popup(surface); + reset_xdg_surface(surface); } static void xdg_popup_get_position(struct wlr_xdg_popup *popup,