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
This commit is contained in:
Jonas Ådahl 2016-01-28 17:14:06 +08:00
parent 2114f2eb9f
commit 3b3f40a1aa
8 changed files with 106 additions and 11 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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.

View File

@ -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);

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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,