wayland: Simplify MetaSelectionSourceWayland

Instead of taking resource and send/cancel funcs, take a
MetaWaylandDataSource, which exposes all the vfuncs to do the same on the
internal resource.

This has the added side effect that only MetaWaylandDataSource has a
pointer to the wl_resource, which may be unset untimely.

Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/842
This commit is contained in:
Carlos Garnacho 2019-10-11 17:09:26 +02:00
parent 227d272049
commit ea4665bf51
4 changed files with 31 additions and 61 deletions

View File

@ -25,6 +25,8 @@
#include <wayland-server.h> #include <wayland-server.h>
#include "meta/meta-selection-source.h" #include "meta/meta-selection-source.h"
#include "wayland/meta-wayland-data-device.h"
#include "wayland/meta-wayland-data-device-private.h"
#define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ()) #define META_TYPE_SELECTION_SOURCE_WAYLAND (meta_selection_source_wayland_get_type ())
@ -33,14 +35,6 @@ G_DECLARE_FINAL_TYPE (MetaSelectionSourceWayland,
META, SELECTION_SOURCE_WAYLAND, META, SELECTION_SOURCE_WAYLAND,
MetaSelectionSource) MetaSelectionSource)
typedef void (* MetaWaylandSendFunc) (struct wl_resource *resource, MetaSelectionSource * meta_selection_source_wayland_new (MetaWaylandDataSource *source);
const char *mimetype,
int fd);
typedef void (* MetaWaylandCancelFunc) (struct wl_resource *resource);
MetaSelectionSource * meta_selection_source_wayland_new (struct wl_resource *resource,
GList *mime_types,
MetaWaylandSendFunc send_func,
MetaWaylandCancelFunc cancel_func);
#endif /* META_SELECTION_SOURCE_WAYLAND_H */ #endif /* META_SELECTION_SOURCE_WAYLAND_H */

View File

@ -29,10 +29,8 @@
struct _MetaSelectionSourceWayland struct _MetaSelectionSourceWayland
{ {
MetaSelectionSource parent_instance; MetaSelectionSource parent_instance;
MetaWaylandDataSource *data_source;
GList *mimetypes; GList *mimetypes;
MetaWaylandSendFunc send_func;
MetaWaylandCancelFunc cancel_func;
struct wl_resource *resource;
}; };
G_DEFINE_TYPE (MetaSelectionSourceWayland, meta_selection_source_wayland, G_DEFINE_TYPE (MetaSelectionSourceWayland, meta_selection_source_wayland,
@ -85,7 +83,8 @@ meta_selection_source_wayland_read_async (MetaSelectionSource *source,
g_task_set_source_tag (task, meta_selection_source_wayland_read_async); g_task_set_source_tag (task, meta_selection_source_wayland_read_async);
stream = g_unix_input_stream_new (pipe_fds[0], TRUE); stream = g_unix_input_stream_new (pipe_fds[0], TRUE);
source_wayland->send_func (source_wayland->resource, mimetype, pipe_fds[1]); meta_wayland_data_source_send (source_wayland->data_source,
mimetype, pipe_fds[1]);
close (pipe_fds[1]); close (pipe_fds[1]);
g_task_return_pointer (task, stream, g_object_unref); g_task_return_pointer (task, stream, g_object_unref);
@ -119,7 +118,7 @@ meta_selection_source_wayland_deactivated (MetaSelectionSource *source)
MetaSelectionSourceWayland *source_wayland = MetaSelectionSourceWayland *source_wayland =
META_SELECTION_SOURCE_WAYLAND (source); META_SELECTION_SOURCE_WAYLAND (source);
source_wayland->cancel_func (source_wayland->resource); meta_wayland_data_source_cancel (source_wayland->data_source);
META_SELECTION_SOURCE_CLASS (meta_selection_source_wayland_parent_class)->deactivated (source); META_SELECTION_SOURCE_CLASS (meta_selection_source_wayland_parent_class)->deactivated (source);
} }
@ -143,20 +142,29 @@ meta_selection_source_wayland_init (MetaSelectionSourceWayland *source)
{ {
} }
static GList *
copy_string_array_to_list (struct wl_array *array)
{
GList *l = NULL;
char **p;
wl_array_for_each (p, array)
l = g_list_prepend (l, g_strdup (*p));
return l;
}
MetaSelectionSource * MetaSelectionSource *
meta_selection_source_wayland_new (struct wl_resource *resource, meta_selection_source_wayland_new (MetaWaylandDataSource *data_source)
GList *mime_types,
MetaWaylandSendFunc send_func,
MetaWaylandCancelFunc cancel_func)
{ {
MetaSelectionSourceWayland *source_wayland; MetaSelectionSourceWayland *source_wayland;
struct wl_array *mimetypes;
source_wayland = g_object_new (META_TYPE_SELECTION_SOURCE_WAYLAND, NULL); source_wayland = g_object_new (META_TYPE_SELECTION_SOURCE_WAYLAND, NULL);
source_wayland->mimetypes = g_list_copy_deep (mime_types, source_wayland->data_source = data_source;
(GCopyFunc) g_strdup, NULL);
source_wayland->send_func = send_func; mimetypes = meta_wayland_data_source_get_mime_types (data_source);
source_wayland->cancel_func = cancel_func; source_wayland->mimetypes = copy_string_array_to_list (mimetypes);
source_wayland->resource = resource;
return META_SELECTION_SOURCE (source_wayland); return META_SELECTION_SOURCE (source_wayland);
} }

View File

@ -250,7 +250,7 @@ meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source)
return &priv->mime_types; return &priv->mime_types;
} }
static void void
meta_wayland_data_source_cancel (MetaWaylandDataSource *source) meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
{ {
META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source); META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
@ -1152,18 +1152,6 @@ destroy_data_device_icon (struct wl_listener *listener, void *data)
clutter_actor_remove_all_children (drag_grab->feedback_actor); clutter_actor_remove_all_children (drag_grab->feedback_actor);
} }
static GList *
copy_string_array_to_list (struct wl_array *array)
{
GList *l = NULL;
char **p;
wl_array_for_each (p, array)
l = g_list_prepend (l, g_strdup (*p));
return l;
}
void void
meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device, meta_wayland_data_device_start_drag (MetaWaylandDataDevice *data_device,
struct wl_client *client, struct wl_client *client,
@ -1263,7 +1251,6 @@ data_device_start_drag (struct wl_client *client,
MetaWaylandSurface *surface = NULL, *icon_surface = NULL; MetaWaylandSurface *surface = NULL, *icon_surface = NULL;
MetaWaylandDataSource *drag_source = NULL; MetaWaylandDataSource *drag_source = NULL;
MetaSelectionSource *selection_source; MetaSelectionSource *selection_source;
GList *mimetypes;
if (origin_resource) if (origin_resource)
surface = wl_resource_get_user_data (origin_resource); surface = wl_resource_get_user_data (origin_resource);
@ -1299,12 +1286,7 @@ data_device_start_drag (struct wl_client *client,
return; return;
} }
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (drag_source)); selection_source = meta_selection_source_wayland_new (drag_source);
selection_source = meta_selection_source_wayland_new (source_resource,
mimetypes,
wl_data_source_send_send,
wl_data_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
set_selection_source (data_device, META_SELECTION_DND, set_selection_source (data_device, META_SELECTION_DND,
selection_source); selection_source);
g_object_unref (selection_source); g_object_unref (selection_source);
@ -1664,23 +1646,14 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
if (source) if (source)
{ {
MetaWaylandDataSourceWayland *source_wayland =
META_WAYLAND_DATA_SOURCE_WAYLAND (source);
MetaSelectionSource *selection_source; MetaSelectionSource *selection_source;
GList *mimetypes;
meta_wayland_data_source_set_seat (source, seat); meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source), g_object_weak_ref (G_OBJECT (source),
selection_data_source_destroyed, selection_data_source_destroyed,
data_device); data_device);
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source)); selection_source = meta_selection_source_wayland_new (source);
selection_source = meta_selection_source_wayland_new (source_wayland->resource,
mimetypes,
wl_data_source_send_send,
wl_data_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
set_selection_source (data_device, META_SELECTION_CLIPBOARD, set_selection_source (data_device, META_SELECTION_CLIPBOARD,
selection_source); selection_source);
g_object_unref (selection_source); g_object_unref (selection_source);
@ -1805,20 +1778,13 @@ meta_wayland_data_device_set_primary (MetaWaylandDataDevice *data_device,
if (source) if (source)
{ {
MetaSelectionSource *selection_source; MetaSelectionSource *selection_source;
GList *mimetypes;
meta_wayland_data_source_set_seat (source, seat); meta_wayland_data_source_set_seat (source, seat);
g_object_weak_ref (G_OBJECT (source), g_object_weak_ref (G_OBJECT (source),
primary_source_destroyed, primary_source_destroyed,
data_device); data_device);
mimetypes = copy_string_array_to_list (meta_wayland_data_source_get_mime_types (source)); selection_source = meta_selection_source_wayland_new (source);
selection_source = meta_selection_source_wayland_new (META_WAYLAND_DATA_SOURCE_WAYLAND (source)->resource,
mimetypes,
gtk_primary_selection_source_send_send,
gtk_primary_selection_source_send_cancelled);
g_list_free_full (mimetypes, g_free);
set_selection_source (data_device, META_SELECTION_PRIMARY, set_selection_source (data_device, META_SELECTION_PRIMARY,
selection_source); selection_source);
g_object_unref (selection_source); g_object_unref (selection_source);

View File

@ -111,6 +111,8 @@ gboolean meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source, void meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
gboolean has_target); gboolean has_target);
void meta_wayland_data_source_cancel (MetaWaylandDataSource *source);
void meta_wayland_data_source_send (MetaWaylandDataSource *source, void meta_wayland_data_source_send (MetaWaylandDataSource *source,
const gchar *mime_type, const gchar *mime_type,
gint fd); gint fd);