From 5d3b4f0134bdd84ee30648fb401bad7522d23cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 15 Nov 2017 16:02:03 +0800 Subject: [PATCH] wayland/xdg-shell: Fix top-most check when grabbing Move the top-most-popup correctness check to the finish_popup_setup() function after checking the serial. If we pass the serial check, we should have reached a state that if there are any popups they should be the one from the same client. Also avoid failing a client that correctly set the top-most popup at map time, but where at the time of processing the top most popup have already been dismissed by the compositor for some arbitrary reason. https://bugzilla.gnome.org/show_bug.cgi?id=790358 --- src/wayland/meta-wayland-xdg-shell.c | 30 +++++++++++++--------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 99fc9acff..5ca39b318 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -448,7 +448,6 @@ xdg_popup_grab (struct wl_client *client, META_WAYLAND_XDG_POPUP (wl_resource_get_user_data (resource)); MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); MetaWaylandSurface *parent_surface; - MetaWaylandSurface *top_popup; parent_surface = xdg_popup->setup.parent_surface; if (!parent_surface) @@ -459,21 +458,6 @@ xdg_popup_grab (struct wl_client *client, return; } - top_popup = meta_wayland_pointer_get_top_popup (seat->pointer); - if ((top_popup == NULL && - !META_IS_WAYLAND_XDG_SURFACE (parent_surface->role)) || - (top_popup != NULL && parent_surface != top_popup)) - { - MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); - struct wl_resource *xdg_shell_resource = - meta_wayland_xdg_surface_get_shell_resource (xdg_surface); - - wl_resource_post_error (xdg_shell_resource, - ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, - "parent not top most surface"); - return; - } - xdg_popup->setup.grab_seat = seat; xdg_popup->setup.grab_serial = serial; } @@ -794,7 +778,10 @@ scale_placement_rule (MetaPlacementRule *placement_rule, static void finish_popup_setup (MetaWaylandXdgPopup *xdg_popup) { + MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (xdg_popup); MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + struct wl_resource *xdg_shell_resource = + meta_wayland_xdg_surface_get_shell_resource (xdg_surface); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); MetaWaylandSurface *parent_surface; @@ -813,11 +800,22 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup) if (seat) { + MetaWaylandSurface *top_popup; + if (!meta_wayland_seat_can_popup (seat, serial)) { zxdg_popup_v6_send_popup_done (xdg_popup->resource); return; } + + top_popup = meta_wayland_pointer_get_top_popup (seat->pointer); + if (top_popup && parent_surface != top_popup) + { + wl_resource_post_error (xdg_shell_resource, + ZXDG_SHELL_V6_ERROR_NOT_THE_TOPMOST_POPUP, + "parent not top most surface"); + return; + } } xdg_popup->parent_surface = parent_surface;