[mutter] wayland: Add get_toplevel() vfunc to the role class



commit e66f176c294641f86b671c008a2806c03b582573
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Jan 14 17:43:47 2016 +0800

    wayland: Add get_toplevel() vfunc to the role class
    
    How to find the toplevel surface of a surface depends on the surface
    role, so let the roles implement it themself.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763431

 src/wayland/meta-wayland-surface.c   |   54 +++++++++++++++++++++++++--------
 src/wayland/meta-wayland-surface.h   |    3 ++
 src/wayland/meta-wayland-wl-shell.c  |   14 +++++++++
 src/wayland/meta-wayland-xdg-shell.c |   17 ++++++++++
 src/wayland/meta-xwayland.c          |    7 ++++
 5 files changed, 82 insertions(+), 13 deletions(-)
---
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index d3580a0..3d4f0a9 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -133,6 +133,9 @@ static gboolean
 meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
                                         MetaMonitorInfo *info);
 
+static MetaWaylandSurface *
+meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role);
+
 static void
 meta_wayland_surface_role_shell_surface_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role,
                                                    int                                 new_width,
@@ -543,6 +546,16 @@ subsurface_role_commit (MetaWaylandSurfaceRole  *surface_role,
     clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
 }
 
+static MetaWaylandSurface *
+subsurface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  MetaWaylandSurface *surface =
+    meta_wayland_surface_role_get_surface (surface_role);
+  MetaWaylandSurface *parent = surface->sub.parent;
+
+  return meta_wayland_surface_role_get_toplevel (parent->role);
+}
+
 /* A non-subsurface is always desynchronized.
  *
  * A subsurface is effectively synchronized if either its parent is
@@ -1787,23 +1800,25 @@ meta_wayland_surface_drag_dest_update (MetaWaylandSurface *surface)
   surface->dnd.funcs->update (data_device, surface);
 }
 
+MetaWaylandSurface *
+meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface)
+{
+  if (surface->role)
+    return meta_wayland_surface_role_get_toplevel (surface->role);
+  else
+    return NULL;
+}
+
 MetaWindow *
 meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
 {
-  while (surface)
-    {
-      if (surface->window)
-        {
-          if (surface->popup.parent)
-            surface = surface->popup.parent;
-          else
-            return surface->window;
-        }
-      else
-        surface = surface->sub.parent;
-    }
+  MetaWaylandSurface *toplevel;
 
-  return NULL;
+  toplevel = meta_wayland_surface_get_toplevel (surface);
+  if (toplevel)
+    return toplevel->window;
+  else
+    return NULL;
 }
 
 void
@@ -1901,6 +1916,18 @@ meta_wayland_surface_role_is_on_output (MetaWaylandSurfaceRole *surface_role,
     return FALSE;
 }
 
+static MetaWaylandSurface *
+meta_wayland_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  MetaWaylandSurfaceRoleClass *klass;
+
+  klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
+  if (klass->get_toplevel)
+    return klass->get_toplevel (surface_role);
+  else
+    return NULL;
+}
+
 MetaWaylandSurface *
 meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRole *role)
 {
@@ -2056,6 +2083,7 @@ meta_wayland_surface_role_subsurface_class_init (MetaWaylandSurfaceRoleSubsurfac
     META_WAYLAND_SURFACE_ROLE_CLASS (klass);
 
   surface_role_class->commit = subsurface_role_commit;
+  surface_role_class->get_toplevel = subsurface_role_get_toplevel;
 }
 
 cairo_region_t *
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 920949e..85d3371 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -62,6 +62,7 @@ struct _MetaWaylandSurfaceRoleClass
                   MetaWaylandPendingState *pending);
   gboolean (*is_on_output) (MetaWaylandSurfaceRole *surface_role,
                             MetaMonitorInfo        *monitor);
+  MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);
 };
 
 struct _MetaWaylandSerial {
@@ -317,6 +318,8 @@ void                meta_wayland_surface_drag_dest_update    (MetaWaylandSurface
 
 void                meta_wayland_surface_update_outputs (MetaWaylandSurface *surface);
 
+MetaWaylandSurface *meta_wayland_surface_get_toplevel (MetaWaylandSurface *surface);
+
 MetaWindow *        meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
 
 void                meta_wayland_surface_queue_pending_frame_callbacks (MetaWaylandSurface *surface);
diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c
index d4a2e07..135e6cc 100644
--- a/src/wayland/meta-wayland-wl-shell.c
+++ b/src/wayland/meta-wayland-wl-shell.c
@@ -509,6 +509,19 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
     meta_wayland_surface_apply_window_state (surface, pending);
 }
 
+static MetaWaylandSurface *
+wl_shell_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  MetaWaylandSurface *surface =
+    meta_wayland_surface_role_get_surface (surface_role);
+
+  if (surface->wl_shell.state == META_WL_SHELL_SURFACE_STATE_POPUP &&
+      surface->popup.parent)
+    return meta_wayland_surface_get_toplevel (surface->popup.parent);
+  else
+    return meta_wayland_surface_role_get_surface (surface_role);
+}
+
 static void
 wl_shell_surface_role_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role,
                                  int                                 new_width,
@@ -583,6 +596,7 @@ meta_wayland_wl_shell_surface_class_init (MetaWaylandWlShellSurfaceClass *klass)
 
   surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
   surface_role_class->commit = wl_shell_surface_role_commit;
+  surface_role_class->get_toplevel = wl_shell_surface_role_get_toplevel;
 
   shell_surface_role_class =
     META_WAYLAND_SURFACE_ROLE_SHELL_SURFACE_CLASS (klass);
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index b527d9b..833d934 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -588,6 +588,12 @@ xdg_surface_role_commit (MetaWaylandSurfaceRole  *surface_role,
     meta_wayland_surface_apply_window_state (surface, pending);
 }
 
+static MetaWaylandSurface *
+xdg_surface_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  return meta_wayland_surface_role_get_surface (surface_role);
+}
+
 static void
 xdg_surface_role_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role,
                             int                                 new_width,
@@ -664,6 +670,7 @@ meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass)
     META_WAYLAND_SURFACE_ROLE_CLASS (klass);
 
   surface_role_class->commit = xdg_surface_role_commit;
+  surface_role_class->get_toplevel = xdg_surface_role_get_toplevel;
 
   MetaWaylandSurfaceRoleShellSurfaceClass *shell_surface_role_class =
     META_WAYLAND_SURFACE_ROLE_SHELL_SURFACE_CLASS (klass);
@@ -699,6 +706,15 @@ xdg_popup_role_commit (MetaWaylandSurfaceRole  *surface_role,
     meta_wayland_surface_apply_window_state (surface, pending);
 }
 
+static MetaWaylandSurface *
+xdg_popup_role_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  MetaWaylandSurface *surface =
+     meta_wayland_surface_role_get_surface (surface_role);
+
+  return meta_wayland_surface_get_toplevel (surface->popup.parent);
+}
+
 static void
 xdg_popup_role_configure (MetaWaylandSurfaceRoleShellSurface *shell_surface_role,
                           int                                 new_width,
@@ -760,6 +776,7 @@ meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass)
     META_WAYLAND_SURFACE_ROLE_CLASS (klass);
 
   surface_role_class->commit = xdg_popup_role_commit;
+  surface_role_class->get_toplevel = xdg_popup_role_get_toplevel;
 
   MetaWaylandSurfaceRoleShellSurfaceClass *shell_surface_role_class =
     META_WAYLAND_SURFACE_ROLE_SHELL_SURFACE_CLASS (klass);
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index bf49f41..e8631c7 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -618,6 +618,12 @@ xwayland_surface_commit (MetaWaylandSurfaceRole  *surface_role,
   meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
 }
 
+static MetaWaylandSurface *
+xwayland_surface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
+{
+  return meta_wayland_surface_role_get_surface (surface_role);
+}
+
 static void
 meta_wayland_surface_role_xwayland_init (MetaWaylandSurfaceRoleXWayland *role)
 {
@@ -631,4 +637,5 @@ meta_wayland_surface_role_xwayland_class_init (MetaWaylandSurfaceRoleXWaylandCla
 
   surface_role_class->assigned = xwayland_surface_assigned;
   surface_role_class->commit = xwayland_surface_commit;
+  surface_role_class->get_toplevel = xwayland_surface_get_toplevel;
 }


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