[mutter] MetaWaylandSurface: Allow passing parameters when assigning role



commit 3b3f40a1aa6a02e3db78e5af695218160038cd6c
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Jan 28 17:14:06 2016 +0800

    MetaWaylandSurface: Allow passing parameters when assigning role
    
    Allow passing parameters (only GObject parameters supported for now) so
    that role assignment can affect the paremeters set during construction.
    
    If a role was already assigned when assigning, the passed parameters
    are set using g_object_set_valist().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769936

 src/wayland/meta-wayland-data-device.c |    3 +-
 src/wayland/meta-wayland-pointer.c     |    3 +-
 src/wayland/meta-wayland-surface.c     |   92 ++++++++++++++++++++++++++++++-
 src/wayland/meta-wayland-surface.h     |    4 +-
 src/wayland/meta-wayland-tablet-tool.c |    3 +-
 src/wayland/meta-wayland-wl-shell.c    |    3 +-
 src/wayland/meta-wayland-xdg-shell.c   |    6 ++-
 src/wayland/meta-xwayland.c            |    3 +-
 8 files changed, 106 insertions(+), 11 deletions(-)
---
diff --git a/src/wayland/meta-wayland-data-device.c b/src/wayland/meta-wayland-data-device.c
index 96d03c9..fbc42ec 100644
--- a/src/wayland/meta-wayland-data-device.c
+++ b/src/wayland/meta-wayland-data-device.c
@@ -1174,7 +1174,8 @@ data_device_start_drag (struct wl_client *client,
 
   if (icon_resource &&
       !meta_wayland_surface_assign_role (icon_surface,
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_DND))
+                                         META_TYPE_WAYLAND_SURFACE_ROLE_DND,
+                                         NULL))
     {
       wl_resource_post_error (resource, WL_DATA_DEVICE_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c
index d16a0bc..d919330 100644
--- a/src/wayland/meta-wayland-pointer.c
+++ b/src/wayland/meta-wayland-pointer.c
@@ -1005,7 +1005,8 @@ pointer_set_cursor (struct wl_client *client,
 
   if (surface &&
       !meta_wayland_surface_assign_role (surface,
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR))
+                                         META_TYPE_WAYLAND_SURFACE_ROLE_CURSOR,
+                                         NULL))
     {
       wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index c3505d2..f4dfd1f 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -29,6 +29,7 @@
 #include <clutter/wayland/clutter-wayland-surface.h>
 #include <cogl/cogl-wayland-server.h>
 
+#include <gobject/gvaluecollector.h>
 #include <wayland-server.h>
 #include "gtk-shell-server-protocol.h"
 
@@ -168,13 +169,92 @@ static void
 meta_wayland_surface_role_shell_surface_managed (MetaWaylandSurfaceRoleShellSurface *shell_surface_role,
                                                  MetaWindow                         *window);
 
+static void
+unset_param_value (GParameter *param)
+{
+  g_value_unset (&param->value);
+}
+
+static GArray *
+role_assignment_valist_to_params (GType       role_type,
+                                  const char *first_property_name,
+                                  va_list     var_args)
+{
+  GObjectClass *object_class;
+  const char *property_name = first_property_name;
+  GArray *params;
+
+  object_class = g_type_class_ref (role_type);
+
+  params = g_array_new (FALSE, FALSE, sizeof (GParameter));
+  g_array_set_clear_func (params, (GDestroyNotify) unset_param_value);
+
+  while (property_name)
+    {
+      GParameter param = {
+        .name = property_name,
+        .value = G_VALUE_INIT
+      };
+      GParamSpec *pspec;
+      GType ptype;
+      gchar *error = NULL;
+
+      pspec = g_object_class_find_property (object_class,
+                                            property_name);
+      g_assert (pspec);
+
+      ptype = G_PARAM_SPEC_VALUE_TYPE (pspec);
+      G_VALUE_COLLECT_INIT (&param.value, ptype, var_args, 0, &error);
+      g_assert (!error);
+
+      g_array_append_val (params, param);
+
+      property_name = va_arg (var_args, const char *);
+    }
+
+  g_type_class_unref (object_class);
+
+  return params;
+}
+
 gboolean
 meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
-                                  GType               role_type)
+                                  GType               role_type,
+                                  const char         *first_property_name,
+                                  ...)
 {
+  va_list var_args;
+
   if (!surface->role)
     {
-      surface->role = g_object_new (role_type, "surface", surface, NULL);
+      if (first_property_name)
+        {
+          GArray *params;
+          GParameter param;
+
+          va_start (var_args, first_property_name);
+          params = role_assignment_valist_to_params (role_type,
+                                                     first_property_name,
+                                                     var_args);
+          va_end (var_args);
+
+          param = (GParameter) {
+            .name = "surface",
+            .value = G_VALUE_INIT
+          };
+          g_value_init (&param.value, META_TYPE_WAYLAND_SURFACE);
+          g_value_set_object (&param.value, surface);
+          g_array_append_val (params, param);
+
+          surface->role = g_object_newv (role_type, params->len,
+                                         (GParameter *) params->data);
+
+          g_array_unref (params);
+        }
+      else
+        {
+          surface->role = g_object_new (role_type, "surface", surface, NULL);
+        }
 
       meta_wayland_surface_role_assigned (surface->role);
 
@@ -193,6 +273,11 @@ meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
     }
   else
     {
+      va_start (var_args, first_property_name);
+      g_object_set_valist (G_OBJECT (surface->role),
+                           first_property_name, var_args);
+      va_end (var_args);
+
       return TRUE;
     }
 }
@@ -1599,7 +1684,8 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
     }
 
   if (!meta_wayland_surface_assign_role (surface,
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE))
+                                         META_TYPE_WAYLAND_SURFACE_ROLE_SUBSURFACE,
+                                         NULL))
     {
       /* FIXME: There is no subcompositor "role" error yet, so lets just use something
        * similar until there is.
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index fd1ef41..967b56f 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -243,7 +243,9 @@ MetaWaylandSurface *meta_wayland_surface_create (MetaWaylandCompositor *composit
                                                  guint32                id);
 
 gboolean            meta_wayland_surface_assign_role (MetaWaylandSurface *surface,
-                                                      GType               role_type);
+                                                      GType               role_type,
+                                                      const char         *first_property_name,
+                                                      ...);
 
 MetaWaylandBuffer  *meta_wayland_surface_get_buffer (MetaWaylandSurface *surface);
 
diff --git a/src/wayland/meta-wayland-tablet-tool.c b/src/wayland/meta-wayland-tablet-tool.c
index 88efdb0..c3df2d9 100644
--- a/src/wayland/meta-wayland-tablet-tool.c
+++ b/src/wayland/meta-wayland-tablet-tool.c
@@ -443,7 +443,8 @@ tool_set_cursor (struct wl_client   *client,
 
   if (surface &&
       !meta_wayland_surface_assign_role (surface,
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR))
+                                         META_TYPE_WAYLAND_SURFACE_ROLE_TABLET_CURSOR,
+                                         NULL))
     {
       wl_resource_post_error (resource, WL_POINTER_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
diff --git a/src/wayland/meta-wayland-wl-shell.c b/src/wayland/meta-wayland-wl-shell.c
index 29b89f6..927c593 100644
--- a/src/wayland/meta-wayland-wl-shell.c
+++ b/src/wayland/meta-wayland-wl-shell.c
@@ -518,7 +518,8 @@ wl_shell_get_shell_surface (struct wl_client   *client,
     }
 
   if (!meta_wayland_surface_assign_role (surface,
-                                         META_TYPE_WAYLAND_WL_SHELL_SURFACE))
+                                         META_TYPE_WAYLAND_WL_SHELL_SURFACE,
+                                         NULL))
     {
       wl_resource_post_error (resource, WL_SHELL_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index 5321467..0adc3df 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -767,7 +767,8 @@ xdg_shell_get_xdg_surface (struct wl_client   *client,
       return;
     }
 
-  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_SURFACE))
+  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_SURFACE,
+                                         NULL))
     {
       wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
@@ -821,7 +822,8 @@ xdg_shell_get_xdg_popup (struct wl_client   *client,
       return;
     }
 
-  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_POPUP))
+  if (!meta_wayland_surface_assign_role (surface, META_TYPE_WAYLAND_XDG_POPUP,
+                                         NULL))
     {
       wl_resource_post_error (resource, XDG_SHELL_ERROR_ROLE,
                               "wl_surface@%d already has a different role",
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 0cf966e..b40bbcf 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -56,7 +56,8 @@ associate_window_with_surface (MetaWindow         *window,
   MetaDisplay *display = window->display;
 
   if (!meta_wayland_surface_assign_role (surface,
-                                         META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND))
+                                         META_TYPE_WAYLAND_SURFACE_ROLE_XWAYLAND,
+                                         NULL))
     {
       wl_resource_post_error (surface->resource,
                               WL_DISPLAY_ERROR_INVALID_OBJECT,


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