From 229a143eac5e16c3a0962c58fbb8878b91bafecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 21 Jan 2016 17:01:08 +0800 Subject: [PATCH] wayland: Add 'MetaWaylandPopupSurface' bridge between popup and surface Add a bridge between the MetaWaylandPopup object and the corresponding popup surface role. This bridge replaces communicating dismissed and unmapped popup events. https://bugzilla.gnome.org/show_bug.cgi?id=763431 --- src/wayland/meta-wayland-pointer.c | 8 +-- src/wayland/meta-wayland-pointer.h | 4 +- src/wayland/meta-wayland-popup.c | 62 +++++++++++++------- src/wayland/meta-wayland-popup.h | 24 ++++++-- src/wayland/meta-wayland-surface.c | 21 ------- src/wayland/meta-wayland-surface.h | 4 -- src/wayland/meta-wayland-types.h | 1 + src/wayland/meta-wayland-wl-shell.c | 65 ++++++++++++++------- src/wayland/meta-wayland-xdg-shell.c | 85 +++++++++++++++++----------- 9 files changed, 164 insertions(+), 110 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 6ae5754f3..798583bfd 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -889,8 +889,8 @@ meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer) } MetaWaylandPopup * -meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, - MetaWaylandSurface *surface) +meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface) { MetaWaylandPopupGrab *grab; @@ -899,11 +899,11 @@ meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, return NULL; if (pointer->grab == &pointer->default_grab) - grab = meta_wayland_popup_grab_create (pointer, surface); + grab = meta_wayland_popup_grab_create (pointer, popup_surface); else grab = (MetaWaylandPopupGrab*)pointer->grab; - return meta_wayland_popup_create (surface, grab); + return meta_wayland_popup_create (popup_surface, grab); } void diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index c016bc1ec..4e97ec962 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -117,8 +117,8 @@ void meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer, void meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer); -MetaWaylandPopup *meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, - MetaWaylandSurface *popup); +MetaWaylandPopup *meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface); void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer); diff --git a/src/wayland/meta-wayland-popup.c b/src/wayland/meta-wayland-popup.c index 174a6d86a..93fea932e 100644 --- a/src/wayland/meta-wayland-popup.c +++ b/src/wayland/meta-wayland-popup.c @@ -48,6 +48,9 @@ #include "meta-wayland-private.h" #include "meta-wayland-surface.h" +G_DEFINE_INTERFACE (MetaWaylandPopupSurface, meta_wayland_popup_surface, + G_TYPE_OBJECT); + struct _MetaWaylandPopupGrab { MetaWaylandPointerGrab generic; @@ -59,11 +62,9 @@ struct _MetaWaylandPopupGrab struct _MetaWaylandPopup { MetaWaylandPopupGrab *grab; - MetaWaylandSurface *surface; - struct wl_listener surface_destroy_listener; - struct wl_signal destroy_signal; - - struct wl_list link; + struct wl_listener surface_destroy_listener; + MetaWaylandPopupSurface *popup_surface; + struct wl_list link; }; static void @@ -73,6 +74,29 @@ meta_wayland_popup_grab_begin (MetaWaylandPopupGrab *grab, static void meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab); +static void +meta_wayland_popup_surface_default_init (MetaWaylandPopupSurfaceInterface *iface) +{ +} + +static void +meta_wayland_popup_surface_done (MetaWaylandPopupSurface *popup_surface) +{ + META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->done (popup_surface); +} + +static void +meta_wayland_popup_surface_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->dismiss (popup_surface); +} + +static MetaWaylandSurface * +meta_wayland_popup_surface_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + return META_WAYLAND_POPUP_SURFACE_GET_IFACE (popup_surface)->get_surface (popup_surface); +} + static void popup_grab_focus (MetaWaylandPointerGrab *grab, MetaWaylandSurface *surface) @@ -115,9 +139,11 @@ static MetaWaylandPointerGrabInterface popup_grab_interface = { }; MetaWaylandPopupGrab * -meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, - MetaWaylandSurface *surface) +meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface) { + MetaWaylandSurface *surface = + meta_wayland_popup_surface_get_surface (popup_surface); struct wl_client *client = wl_resource_get_client (surface->resource); MetaWaylandPopupGrab *grab; @@ -170,7 +196,7 @@ meta_wayland_popup_grab_end (MetaWaylandPopupGrab *grab) wl_list_for_each_safe (popup, tmp, &grab->all_popups, link) { - meta_wayland_surface_popup_done (popup->surface); + meta_wayland_popup_surface_done (popup->popup_surface); meta_wayland_popup_destroy (popup); } @@ -191,7 +217,7 @@ meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab *grab) g_assert (!wl_list_empty (&grab->all_popups)); popup = wl_container_of (grab->all_popups.next, popup, link); - return popup->surface; + return meta_wayland_popup_surface_get_surface (popup->popup_surface); } gboolean @@ -203,7 +229,7 @@ meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab) void meta_wayland_popup_destroy (MetaWaylandPopup *popup) { - wl_signal_emit (&popup->destroy_signal, popup); + meta_wayland_popup_surface_dismiss (popup->popup_surface); wl_list_remove (&popup->surface_destroy_listener.link); wl_list_remove (&popup->link); @@ -227,12 +253,6 @@ meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup) return meta_wayland_popup_grab_get_top_popup (popup->grab); } -struct wl_signal * -meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup) -{ - return &popup->destroy_signal; -} - static void on_popup_surface_destroy (struct wl_listener *listener, void *data) @@ -244,9 +264,11 @@ on_popup_surface_destroy (struct wl_listener *listener, } MetaWaylandPopup * -meta_wayland_popup_create (MetaWaylandSurface *surface, - MetaWaylandPopupGrab *grab) +meta_wayland_popup_create (MetaWaylandPopupSurface *popup_surface, + MetaWaylandPopupGrab *grab) { + MetaWaylandSurface *surface = + meta_wayland_popup_surface_get_surface (popup_surface); MetaWaylandPopup *popup; /* Don't allow creating popups if the grab has a different client. */ @@ -255,10 +277,8 @@ meta_wayland_popup_create (MetaWaylandSurface *surface, popup = g_slice_new0 (MetaWaylandPopup); popup->grab = grab; - popup->surface = surface; + popup->popup_surface = popup_surface; popup->surface_destroy_listener.notify = on_popup_surface_destroy; - wl_signal_init (&popup->destroy_signal); - if (surface->xdg_popup) { wl_resource_add_destroy_listener (surface->xdg_popup, diff --git a/src/wayland/meta-wayland-popup.h b/src/wayland/meta-wayland-popup.h index 7e4a3a34a..eab3a9b1a 100644 --- a/src/wayland/meta-wayland-popup.h +++ b/src/wayland/meta-wayland-popup.h @@ -27,8 +27,22 @@ #include "meta-wayland-types.h" #include "meta-wayland-pointer.h" -MetaWaylandPopupGrab *meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, - MetaWaylandSurface *surface); +#define META_TYPE_WAYLAND_POPUP_SURFACE (meta_wayland_popup_surface_get_type ()) +G_DECLARE_INTERFACE (MetaWaylandPopupSurface, meta_wayland_popup_surface, + META, WAYLAND_POPUP_SURFACE, + GObject); + +struct _MetaWaylandPopupSurfaceInterface +{ + GTypeInterface parent_iface; + + void (*done) (MetaWaylandPopupSurface *popup_surface); + void (*dismiss) (MetaWaylandPopupSurface *popup_surface); + MetaWaylandSurface *(*get_surface) (MetaWaylandPopupSurface *popup_surface); +}; + +MetaWaylandPopupGrab *meta_wayland_popup_grab_create (MetaWaylandPointer *pointer, + MetaWaylandPopupSurface *popup_surface); void meta_wayland_popup_grab_destroy (MetaWaylandPopupGrab *grab); @@ -36,8 +50,8 @@ MetaWaylandSurface *meta_wayland_popup_grab_get_top_popup (MetaWaylandPopupGrab gboolean meta_wayland_pointer_grab_is_popup_grab (MetaWaylandPointerGrab *grab); -MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandSurface *surface, - MetaWaylandPopupGrab *grab); +MetaWaylandPopup *meta_wayland_popup_create (MetaWaylandPopupSurface *surface, + MetaWaylandPopupGrab *grab); void meta_wayland_popup_destroy (MetaWaylandPopup *popup); @@ -45,6 +59,4 @@ void meta_wayland_popup_dismiss (MetaWaylandPopup *popup); MetaWaylandSurface *meta_wayland_popup_get_top_popup (MetaWaylandPopup *popup); -struct wl_signal *meta_wayland_popup_get_destroy_signal (MetaWaylandPopup *popup); - #endif /* META_WAYLAND_POPUP_H */ diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index b66dd94be..c86d72f99 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -149,9 +149,6 @@ meta_wayland_surface_role_shell_surface_ping (MetaWaylandSurfaceRoleShellSurface static void meta_wayland_surface_role_shell_surface_close (MetaWaylandSurfaceRoleShellSurface *shell_surface_role); -static void -meta_wayland_surface_role_shell_surface_popup_done (MetaWaylandSurfaceRoleShellSurface *shell_surface_role); - static void meta_wayland_surface_role_shell_surface_managed (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, MetaWindow *window); @@ -1690,15 +1687,6 @@ meta_wayland_surface_delete (MetaWaylandSurface *surface) meta_wayland_surface_role_shell_surface_close (shell_surface_role); } -void -meta_wayland_surface_popup_done (MetaWaylandSurface *surface) -{ - MetaWaylandSurfaceRoleShellSurface *shell_surface_role = - META_WAYLAND_SURFACE_ROLE_SHELL_SURFACE (surface->role); - - meta_wayland_surface_role_shell_surface_popup_done (shell_surface_role); -} - void meta_wayland_surface_window_managed (MetaWaylandSurface *surface, MetaWindow *window) @@ -1927,15 +1915,6 @@ meta_wayland_surface_role_shell_surface_close (MetaWaylandSurfaceRoleShellSurfac shell_surface_role_class->close (shell_surface_role); } -static void -meta_wayland_surface_role_shell_surface_popup_done (MetaWaylandSurfaceRoleShellSurface *shell_surface_role) -{ - MetaWaylandSurfaceRoleShellSurfaceClass *shell_surface_role_class = - META_WAYLAND_SURFACE_ROLE_SHELL_SURFACE_GET_CLASS (shell_surface_role); - - shell_surface_role_class->popup_done (shell_surface_role); -} - static void meta_wayland_surface_role_shell_surface_managed (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, MetaWindow *window) diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h index 9ac4659d8..8a000230d 100644 --- a/src/wayland/meta-wayland-surface.h +++ b/src/wayland/meta-wayland-surface.h @@ -100,7 +100,6 @@ struct _MetaWaylandSurfaceRoleShellSurfaceClass void (*ping) (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, uint32_t serial); void (*close) (MetaWaylandSurfaceRoleShellSurface *shell_surface_role); - void (*popup_done) (MetaWaylandSurfaceRoleShellSurface *shell_surface_role); }; #define META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE (meta_wayland_surface_role_subsurface_get_type ()) @@ -231,7 +230,6 @@ struct _MetaWaylandSurface struct wl_listener parent_destroy_listener; MetaWaylandPopup *popup; - struct wl_listener destroy_listener; } popup; /* wl_shell_surface */ @@ -305,8 +303,6 @@ void meta_wayland_surface_ping (MetaWaylandSurface *surface, guint32 serial); void meta_wayland_surface_delete (MetaWaylandSurface *surface); -void meta_wayland_surface_popup_done (MetaWaylandSurface *surface); - /* Drag dest functions */ void meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface *surface, MetaWaylandDataOffer *offer); diff --git a/src/wayland/meta-wayland-types.h b/src/wayland/meta-wayland-types.h index bea5e20aa..b07001c1e 100644 --- a/src/wayland/meta-wayland-types.h +++ b/src/wayland/meta-wayland-types.h @@ -28,6 +28,7 @@ typedef struct _MetaWaylandPointerGrab MetaWaylandPointerGrab; typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface; typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab; typedef struct _MetaWaylandPopup MetaWaylandPopup; +typedef struct _MetaWaylandPopupSurface MetaWaylandPopupSurface; typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard; typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab; typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface; diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c index 2a28f4887..c3f40bf1a 100644 --- a/src/wayland/meta-wayland-wl-shell.c +++ b/src/wayland/meta-wayland-wl-shell.c @@ -39,9 +39,14 @@ struct _MetaWaylandWlShellSurface MetaWaylandSurfaceRoleShellSurface parent; }; -G_DEFINE_TYPE (MetaWaylandWlShellSurface, - meta_wayland_wl_shell_surface, - META_TYPE_WAYLAND_SURFACE_ROLE_SHELL_SURFACE); +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWaylandWlShellSurface, + meta_wayland_wl_shell_surface, + META_TYPE_WAYLAND_SURFACE_ROLE_SHELL_SURFACE, + G_IMPLEMENT_INTERFACE (META_TYPE_WAYLAND_POPUP_SURFACE, + popup_surface_iface_init)); static void sync_wl_shell_parent_relationship (MetaWaylandSurface *surface, @@ -248,23 +253,17 @@ handle_wl_shell_popup_parent_destroyed (struct wl_listener *listener, surface->popup.parent = NULL; } -static void -handle_wl_shell_popup_destroyed (struct wl_listener *listener, - void *data) -{ - MetaWaylandSurface *surface = - wl_container_of (listener, surface, popup.destroy_listener); - - surface->popup.popup = NULL; -} - static void create_popup (MetaWaylandSurface *surface) { + MetaWaylandWlShellSurface *wl_shell_surface = + META_WAYLAND_WL_SHELL_SURFACE (surface->role); + MetaWaylandPopupSurface *popup_surface = + META_WAYLAND_POPUP_SURFACE (wl_shell_surface); MetaWaylandSeat *seat = surface->wl_shell.popup_seat; MetaWaylandPopup *popup; - popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); + popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, popup_surface); if (!popup) { wl_shell_surface_send_popup_done (surface->wl_shell_surface); @@ -272,9 +271,6 @@ create_popup (MetaWaylandSurface *surface) } surface->popup.popup = popup; - surface->popup.destroy_listener.notify = handle_wl_shell_popup_destroyed; - wl_signal_add (meta_wayland_popup_get_destroy_signal (popup), - &surface->popup.destroy_listener); } static void @@ -583,16 +579,46 @@ wl_shell_surface_role_close (MetaWaylandSurfaceRoleShellSurface *shell_surface_r } static void -wl_shell_surface_role_popup_done (MetaWaylandSurfaceRoleShellSurface *shell_surface_role) +meta_wayland_wl_shell_surface_popup_done (MetaWaylandPopupSurface *popup_surface) { MetaWaylandSurfaceRole *surface_role = - META_WAYLAND_SURFACE_ROLE (shell_surface_role); + META_WAYLAND_SURFACE_ROLE (popup_surface); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); wl_shell_surface_send_popup_done (surface->wl_shell_surface); } +static void +meta_wayland_wl_shell_surface_popup_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + + surface->popup.popup = NULL; + + meta_wayland_surface_destroy_window (surface); +} + +static MetaWaylandSurface * +meta_wayland_wl_shell_surface_popup_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface) +{ + iface->done = meta_wayland_wl_shell_surface_popup_done; + iface->dismiss = meta_wayland_wl_shell_surface_popup_dismiss; + iface->get_surface = meta_wayland_wl_shell_surface_popup_get_surface; +} + static void meta_wayland_wl_shell_surface_init (MetaWaylandWlShellSurface *wl_shell_surface) { @@ -614,7 +640,6 @@ meta_wayland_wl_shell_surface_class_init (MetaWaylandWlShellSurfaceClass *klass) shell_surface_role_class->managed = wl_shell_surface_role_managed; shell_surface_role_class->ping = wl_shell_surface_role_ping; shell_surface_role_class->close = wl_shell_surface_role_close; - shell_surface_role_class->popup_done = wl_shell_surface_role_popup_done; } void diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 541c37786..37c7b4d64 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -52,9 +52,14 @@ struct _MetaWaylandXdgPopup MetaWaylandSurfaceRoleShellSurface parent; }; -G_DEFINE_TYPE (MetaWaylandXdgPopup, - meta_wayland_xdg_popup, - META_TYPE_WAYLAND_SURFACE_ROLE_SHELL_SURFACE); +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaWaylandXdgPopup, + meta_wayland_xdg_popup, + META_TYPE_WAYLAND_SURFACE_ROLE_SHELL_SURFACE, + G_IMPLEMENT_INTERFACE (META_TYPE_WAYLAND_POPUP_SURFACE, + popup_surface_iface_init)); static void xdg_shell_destroy (struct wl_client *client, @@ -393,28 +398,6 @@ handle_popup_parent_destroyed (struct wl_listener *listener, meta_wayland_surface_destroy_window (surface); } -static void -handle_popup_destroyed (struct wl_listener *listener, - void *data) -{ - MetaWaylandPopup *popup = data; - MetaWaylandSurface *top_popup; - MetaWaylandSurface *surface = - wl_container_of (listener, surface, popup.destroy_listener); - - top_popup = meta_wayland_popup_get_top_popup (popup); - if (surface != top_popup) - { - wl_resource_post_error (surface->xdg_shell_resource, - XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP, - "destroyed popup not top most popup"); - } - - surface->popup.popup = NULL; - - meta_wayland_surface_destroy_window (surface); -} - static void xdg_shell_get_xdg_popup (struct wl_client *client, struct wl_resource *resource, @@ -428,6 +411,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, { struct wl_resource *popup_resource; MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource); + MetaWaylandPopupSurface *popup_surface; MetaWaylandSurface *parent_surf = wl_resource_get_user_data (parent_resource); MetaWaylandSurface *top_popup; MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource); @@ -499,7 +483,9 @@ xdg_shell_get_xdg_popup (struct wl_client *client, meta_wayland_surface_set_window (surface, window); meta_window_focus (window, meta_display_get_current_time (display)); - popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, surface); + popup_surface = META_WAYLAND_POPUP_SURFACE (surface->role); + popup = meta_wayland_pointer_start_popup_grab (&seat->pointer, + popup_surface); if (popup == NULL) { xdg_popup_send_popup_done (surface->xdg_popup); @@ -507,10 +493,7 @@ xdg_shell_get_xdg_popup (struct wl_client *client, return; } - surface->popup.destroy_listener.notify = handle_popup_destroyed; surface->popup.popup = popup; - wl_signal_add (meta_wayland_popup_get_destroy_signal (popup), - &surface->popup.destroy_listener); } static const struct xdg_shell_interface meta_wayland_xdg_shell_interface = { @@ -814,16 +797,55 @@ xdg_popup_role_ping (MetaWaylandSurfaceRoleShellSurface *shell_surface_role, } static void -xdg_popup_role_popup_done (MetaWaylandSurfaceRoleShellSurface *shell_surface_role) +meta_wayland_xdg_popup_done (MetaWaylandPopupSurface *popup_surface) { MetaWaylandSurfaceRole *surface_role = - META_WAYLAND_SURFACE_ROLE (shell_surface_role); + META_WAYLAND_SURFACE_ROLE (popup_surface); MetaWaylandSurface *surface = meta_wayland_surface_role_get_surface (surface_role); xdg_popup_send_popup_done (surface->xdg_popup); } +static void +meta_wayland_xdg_popup_dismiss (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (popup_surface); + MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (xdg_popup); + MetaWaylandSurface *surface = + meta_wayland_surface_role_get_surface (surface_role); + MetaWaylandSurface *top_popup; + + top_popup = meta_wayland_popup_get_top_popup (surface->popup.popup); + if (surface != top_popup) + { + wl_resource_post_error (surface->xdg_shell_resource, + XDG_SHELL_ERROR_NOT_THE_TOPMOST_POPUP, + "destroyed popup not top most popup"); + } + + surface->popup.popup = NULL; + + meta_wayland_surface_destroy_window (surface); +} + +static MetaWaylandSurface * +meta_wayland_xdg_popup_get_surface (MetaWaylandPopupSurface *popup_surface) +{ + MetaWaylandSurfaceRole *surface_role = + META_WAYLAND_SURFACE_ROLE (popup_surface); + + return meta_wayland_surface_role_get_surface (surface_role); +} + +static void +popup_surface_iface_init (MetaWaylandPopupSurfaceInterface *iface) +{ + iface->done = meta_wayland_xdg_popup_done; + iface->dismiss = meta_wayland_xdg_popup_dismiss; + iface->get_surface = meta_wayland_xdg_popup_get_surface; +} + static void meta_wayland_xdg_popup_init (MetaWaylandXdgPopup *role) { @@ -844,7 +866,6 @@ meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass) shell_surface_role_class->configure = xdg_popup_role_configure; shell_surface_role_class->managed = xdg_popup_role_managed; shell_surface_role_class->ping = xdg_popup_role_ping; - shell_surface_role_class->popup_done = xdg_popup_role_popup_done; } void