[mutter] wayland-surface: Keep a reference to a popup's parent surface



commit 59f348eb1182e44b49053683867fed733c8d3ffc
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue Feb 24 20:53:55 2015 +0100

    wayland-surface: Keep a reference to a popup's parent surface
    
    This will allows us to access the parent while constructing the
    MetaWindow.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745118

 src/wayland/meta-wayland-surface.c |   25 +++++++++++++++++++++++++
 src/wayland/meta-wayland-surface.h |    7 +++++--
 2 files changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index b1364e8..69f6102 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1021,6 +1021,12 @@ xdg_popup_destructor (struct wl_resource *resource)
 {
   MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
 
+  if (surface->popup.parent)
+    {
+      wl_list_remove (&surface->popup.parent_destroy_listener.link);
+      surface->popup.parent = NULL;
+    }
+
   if (surface->popup.popup)
     meta_wayland_popup_dismiss (surface->popup.popup);
 
@@ -1039,6 +1045,20 @@ static const struct xdg_popup_interface meta_wayland_xdg_popup_interface = {
 };
 
 static void
+handle_popup_parent_destroyed (struct wl_listener *listener, void *data)
+{
+  MetaWaylandSurface *surface =
+    wl_container_of (listener, surface, popup.parent_destroy_listener);
+
+  wl_resource_post_error (surface->xdg_popup,
+                          XDG_POPUP_ERROR_NOT_THE_TOPMOST_POPUP,
+                          "destroyed popup not top most popup");
+  surface->popup.parent = NULL;
+
+  destroy_window (surface);
+}
+
+static void
 handle_popup_destroyed (struct wl_listener *listener, void *data)
 {
   MetaWaylandPopup *popup = data;
@@ -1130,6 +1150,11 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
   surface->xdg_popup = popup_resource;
   surface->xdg_shell_resource = resource;
 
+  surface->popup.parent = parent_surf;
+  surface->popup.parent_destroy_listener.notify = handle_popup_parent_destroyed;
+  wl_resource_add_destroy_listener (parent_surf->resource,
+                                    &surface->popup.parent_destroy_listener);
+
   window = meta_window_wayland_new (display, surface);
   meta_window_move_frame (window, FALSE,
                           parent_surf->window->rect.x + x,
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 0f13dfd..9f8b9de 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -102,8 +102,11 @@ struct _MetaWaylandSurface
 
   /* xdg_popup */
   struct {
-      MetaWaylandPopup *popup;
-      struct wl_listener destroy_listener;
+    MetaWaylandSurface *parent;
+    struct wl_listener parent_destroy_listener;
+
+    MetaWaylandPopup *popup;
+    struct wl_listener destroy_listener;
   } popup;
 
   /* wl_subsurface stuff. */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]