[mutter] MetaWaylandSurface: Return top most toplevel window for popups



commit fbd237bc66b745c4495b53b68e6124de8812f82f
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Mar 24 17:23:13 2015 +0800

    MetaWaylandSurface: Return top most toplevel window for popups
    
    Make meta_wayland_surface_get_toplevel_window return the top most window
    in case its a chain of popups. This is to make all popups in a chain
    including the top most surface have the same scale.
    
    The reason for this is that popups are mostly integrated part of the
    user interface of its parent (such as menus). Having them in a different
    scale would look awkward.
    
    Note that this doesn't affect non-popup windows with parent-child
    relationship, because such windows are typically not an integral part of
    the user interface (settings window, dialogs, ..) and can typically be
    moved independently. It would probably make sense to make attached modal
    dialogs have the same scale as their parent windows, but modal dialogs
    are currently not supported for Wayland clients.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=744934

 src/wayland/meta-wayland-surface.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index accec6a..51bcf38 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1588,6 +1588,17 @@ wl_shell_surface_set_fullscreen (struct wl_client *client,
 }
 
 static void
+handle_wl_shell_popup_parent_destroyed (struct wl_listener *listener,
+                                        void *data)
+{
+  MetaWaylandSurface *surface =
+    wl_container_of (listener, surface, popup.parent_destroy_listener);
+
+  wl_list_remove (&surface->popup.parent_destroy_listener.link);
+  surface->popup.parent = NULL;
+}
+
+static void
 wl_shell_surface_set_popup (struct wl_client *client,
                             struct wl_resource *resource,
                             struct wl_resource *seat_resource,
@@ -1615,6 +1626,15 @@ wl_shell_surface_set_popup (struct wl_client *client,
                           parent_surf->window->rect.y + y);
   surface->window->placed = TRUE;
 
+  if (!surface->popup.parent)
+    {
+      surface->popup.parent = parent_surf;
+      surface->popup.parent_destroy_listener.notify =
+        handle_wl_shell_popup_parent_destroyed;
+      wl_resource_add_destroy_listener (parent_surf->resource,
+                                        &surface->popup.parent_destroy_listener);
+    }
+
   meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
 }
 
@@ -2229,9 +2249,14 @@ meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
   while (surface)
     {
       if (surface->window)
-        return surface->window;
-
-      surface = surface->sub.parent;
+        {
+          if (surface->popup.parent)
+            surface = surface->popup.parent;
+          else
+            return surface->window;
+        }
+      else
+        surface = surface->sub.parent;
     }
 
   return NULL;


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