[gtk+] wayland: Add primary clipboard subclass
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: Add primary clipboard subclass
- Date: Sun, 3 Dec 2017 04:56:16 +0000 (UTC)
commit ff577e6c2cc3cacfb7e3d504bafffa20ae45733b
Author: Benjamin Otte <otte redhat com>
Date: Sun Dec 3 05:39:08 2017 +0100
wayland: Add primary clipboard subclass
I decided to put this in a custom subclass, because then I could keep
the whole gtk primary protocol self-contained.
The other option would have been reusing GdkWaylandClipboard, but that
didn't seem worth it, especially because that code needs to interact
with the DND machinery, while the primary doesn't.
gdk/wayland/gdkdevice-wayland.c | 65 +------
gdk/wayland/gdkprimary-wayland.c | 398 ++++++++++++++++++++++++++++++++++++
gdk/wayland/gdkprimary-wayland.h | 41 ++++
gdk/wayland/gdkprivate-wayland.h | 3 -
gdk/wayland/gdkselection-wayland.c | 188 +----------------
gdk/wayland/meson.build | 1 +
6 files changed, 454 insertions(+), 242 deletions(-)
---
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index ca2ea3e..4f0641f 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -34,6 +34,7 @@
#include "gdkdeviceprivate.h"
#include "gdkdevicepadprivate.h"
#include "gdkdevicetoolprivate.h"
+#include "gdkprimary-wayland.h"
#include "gdkseatprivate.h"
#include "pointer-gestures-unstable-v1-client-protocol.h"
#include "tablet-unstable-v2-client-protocol.h"
@@ -233,7 +234,6 @@ struct _GdkWaylandSeat
GdkClipboard *clipboard;
GdkClipboard *primary_clipboard;
- struct gtk_primary_selection_device *primary_data_device;
struct wl_data_device *data_device;
GdkDragContext *drop_context;
@@ -1211,45 +1211,6 @@ static const struct wl_data_device_listener data_device_listener = {
data_device_selection
};
-static void
-primary_selection_data_offer (void *data,
- struct gtk_primary_selection_device *gtk_primary_selection_device,
- struct gtk_primary_selection_offer *gtk_primary_offer)
-{
- GdkWaylandSeat *seat = data;
-
- GDK_NOTE (EVENTS,
- g_message ("primary selection offer, device %p, data offer %p",
- gtk_primary_selection_device, gtk_primary_offer));
-
- gdk_wayland_selection_ensure_primary_offer (seat->display, gtk_primary_offer);
-}
-
-static void
-primary_selection_selection (void *data,
- struct gtk_primary_selection_device *gtk_primary_selection_device,
- struct gtk_primary_selection_offer *gtk_primary_offer)
-{
- GdkWaylandSeat *seat = data;
- GdkAtom selection;
-
- if (!seat->keyboard_focus)
- return;
-
- GDK_NOTE (EVENTS,
- g_message ("primary selection selection, device %p, data offer %p",
- gtk_primary_selection_device, gtk_primary_offer));
-
- selection = gdk_atom_intern_static_string ("PRIMARY");
- gdk_wayland_selection_set_offer (seat->display, selection, gtk_primary_offer);
- /* emit_selection_owner_change (seat->keyboard_focus, selection); */
-}
-
-static const struct gtk_primary_selection_device_listener primary_selection_device_listener = {
- primary_selection_data_offer,
- primary_selection_selection,
-};
-
static GdkDevice * get_scroll_device (GdkWaylandSeat *seat,
enum wl_pointer_axis_source source);
@@ -4796,12 +4757,7 @@ _gdk_wayland_display_create_seat (GdkWaylandDisplay *display_wayland,
if (display_wayland->primary_selection_manager)
{
- seat->primary_data_device =
- gtk_primary_selection_device_manager_get_device (display_wayland->primary_selection_manager,
- seat->wl_seat);
- gtk_primary_selection_device_add_listener (seat->primary_data_device,
- &primary_selection_device_listener, seat);
- seat->primary_clipboard = gdk_wayland_clipboard_new (display);
+ seat->primary_clipboard = gdk_wayland_primary_new (seat);
}
else
{
@@ -5016,23 +4972,6 @@ gdk_wayland_device_set_selection (GdkDevice *gdk_device,
_gdk_wayland_display_get_serial (display_wayland));
}
-void
-gdk_wayland_seat_set_primary (GdkSeat *seat,
- struct gtk_primary_selection_source *source)
-{
- GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
- GdkWaylandDisplay *display_wayland;
- guint32 serial;
-
- if (source)
- {
- display_wayland = GDK_WAYLAND_DISPLAY (gdk_seat_get_display (seat));
- serial = _gdk_wayland_display_get_serial (display_wayland);
- gtk_primary_selection_device_set_selection (wayland_seat->primary_data_device,
- source, serial);
- }
-}
-
/**
* gdk_wayland_seat_get_wl_seat:
* @device: (type GdkWaylandDevice): a #GdkDevice
diff --git a/gdk/wayland/gdkprimary-wayland.c b/gdk/wayland/gdkprimary-wayland.c
new file mode 100644
index 0000000..b83f41a
--- /dev/null
+++ b/gdk/wayland/gdkprimary-wayland.c
@@ -0,0 +1,398 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gdkprimary-wayland.h"
+
+#include "gdkclipboardprivate.h"
+#include "gdkcontentformats.h"
+#include "gdkintl.h"
+#include "gdkprivate-wayland.h"
+#include "gdk-private.h"
+
+#include <glib-unix.h>
+#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
+
+typedef struct _GdkWaylandPrimaryClass GdkWaylandPrimaryClass;
+
+struct _GdkWaylandPrimary
+{
+ GdkClipboard parent;
+
+ struct gtk_primary_selection_device *primary_data_device;
+
+ struct gtk_primary_selection_offer *pending;
+ GdkContentFormatsBuilder *pending_builder;
+
+ struct gtk_primary_selection_offer *offer;
+ GdkContentFormats *offer_formats;
+
+ struct gtk_primary_selection_source *source;
+};
+
+struct _GdkWaylandPrimaryClass
+{
+ GdkClipboardClass parent_class;
+};
+
+G_DEFINE_TYPE (GdkWaylandPrimary, gdk_wayland_primary, GDK_TYPE_CLIPBOARD)
+
+static void
+gdk_wayland_primary_discard_pending (GdkWaylandPrimary *cb)
+{
+ if (cb->pending_builder)
+ {
+ GdkContentFormats *ignore = gdk_content_formats_builder_free (cb->pending_builder);
+ gdk_content_formats_unref (ignore);
+ cb->pending_builder = NULL;
+ }
+ g_clear_pointer (&cb->pending, (GDestroyNotify) gtk_primary_selection_offer_destroy);
+}
+
+static void
+gdk_wayland_primary_discard_offer (GdkWaylandPrimary *cb)
+{
+ g_clear_pointer (&cb->offer_formats, gdk_content_formats_unref);
+ g_clear_pointer (&cb->offer, (GDestroyNotify) gtk_primary_selection_offer_destroy);
+}
+
+static void
+gdk_wayland_primary_discard_source (GdkWaylandPrimary *cb)
+{
+ g_clear_pointer (&cb->source, (GDestroyNotify) wl_data_source_destroy);
+}
+
+static void
+gdk_wayland_primary_finalize (GObject *object)
+{
+ GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (object);
+
+ gdk_wayland_primary_discard_pending (cb);
+ gdk_wayland_primary_discard_offer (cb);
+ gdk_wayland_primary_discard_source (cb);
+
+ G_OBJECT_CLASS (gdk_wayland_primary_parent_class)->finalize (object);
+}
+
+static void
+gdk_wayland_primary_claim_remote (GdkWaylandPrimary *cb,
+ struct gtk_primary_selection_offer *offer,
+ GdkContentFormats *formats)
+{
+ g_return_if_fail (GDK_IS_WAYLAND_PRIMARY (cb));
+
+ if (cb->source)
+ {
+ GDK_NOTE (CLIPBOARD, g_printerr ("%p: Ignoring clipboard offer for self\n", cb));
+ return;
+ }
+
+ gdk_wayland_primary_discard_offer (cb);
+
+ GDK_NOTE (CLIPBOARD, char *s = gdk_content_formats_to_string (formats);
+ g_printerr ("%p: remote clipboard claim for %s\n", cb, s);
+ g_free (s); );
+ cb->offer_formats = formats;
+ cb->offer = offer;
+
+ gdk_clipboard_claim_remote (GDK_CLIPBOARD (cb),
+ cb->offer_formats);
+}
+
+static void
+primary_offer_offer (void *data,
+ struct gtk_primary_selection_offer *offer,
+ const char *type)
+{
+ GdkWaylandPrimary *cb = data;
+
+ if (cb->pending != offer)
+ {
+ GDK_NOTE (SELECTION, g_printerr ("%p: offer for unknown selection %p of %s\n",
+ cb, offer, type));
+ return;
+ }
+
+ gdk_content_formats_builder_add_mime_type (cb->pending_builder, type);
+}
+
+static const struct gtk_primary_selection_offer_listener primary_offer_listener = {
+ primary_offer_offer,
+};
+
+static void
+primary_selection_data_offer (void *data,
+ struct gtk_primary_selection_device *device,
+ struct gtk_primary_selection_offer *offer)
+{
+ GdkWaylandPrimary *cb = data;
+
+ GDK_NOTE (SELECTION, g_printerr ("%p: new primary offer %p\n",
+ cb, offer));
+
+ gdk_wayland_primary_discard_pending (cb);
+
+ cb->pending = offer;
+ gtk_primary_selection_offer_add_listener (offer,
+ &primary_offer_listener,
+ cb);
+
+ cb->pending_builder = gdk_content_formats_builder_new ();
+}
+
+static void
+primary_selection_selection (void *data,
+ struct gtk_primary_selection_device *device,
+ struct gtk_primary_selection_offer *offer)
+{
+ GdkWaylandPrimary *cb = data;
+ GdkContentFormats *formats;
+
+ if (offer == NULL)
+ {
+ gdk_wayland_primary_claim_remote (cb, NULL, gdk_content_formats_new (NULL, 0));
+ return;
+ }
+
+ if (cb->pending != offer)
+ {
+ GDK_NOTE (SELECTION, g_printerr ("%p: ignoring unknown data offer %p\n",
+ cb, offer));
+ return;
+ }
+
+ formats = gdk_content_formats_builder_free (cb->pending_builder);
+ cb->pending_builder = NULL;
+ cb->pending = NULL;
+
+ gdk_wayland_primary_claim_remote (cb, offer, formats);
+}
+
+static const struct gtk_primary_selection_device_listener primary_selection_device_listener = {
+ primary_selection_data_offer,
+ primary_selection_selection,
+};
+
+static void
+gdk_wayland_primary_write_done (GObject *clipboard,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ if (!gdk_clipboard_write_finish (GDK_CLIPBOARD (clipboard), result, &error))
+ {
+ GDK_NOTE (SELECTION, g_printerr ("%p: failed to write stream: %s\n", clipboard, error->message));
+ g_error_free (error);
+ }
+}
+
+static void
+gdk_wayland_primary_data_source_send (void *data,
+ struct gtk_primary_selection_source *source,
+ const char *mime_type,
+ int32_t fd)
+{
+ GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (data);
+ GOutputStream *stream;
+
+ GDK_NOTE (SELECTION, g_printerr ("%p: data source send request for %s on fd %d\n",
+ source, mime_type, fd));
+
+ mime_type = gdk_intern_mime_type (mime_type);
+ stream = g_unix_output_stream_new (fd, TRUE);
+
+ gdk_clipboard_write_async (GDK_CLIPBOARD (cb),
+ mime_type,
+ stream,
+ G_PRIORITY_DEFAULT,
+ NULL,
+ gdk_wayland_primary_write_done,
+ cb);
+ g_object_unref (stream);
+}
+
+static void
+gdk_wayland_primary_data_source_cancelled (void *data,
+ struct gtk_primary_selection_source *source)
+{
+ GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (data);
+
+ GDK_NOTE (CLIPBOARD, g_printerr ("%p: data source cancelled\n", data));
+
+ if (cb->source == source)
+ {
+ gdk_wayland_primary_discard_source (cb);
+ gdk_wayland_primary_claim_remote (cb, NULL, gdk_content_formats_new (NULL, 0));
+ }
+}
+
+static const struct gtk_primary_selection_source_listener primary_source_listener = {
+ gdk_wayland_primary_data_source_send,
+ gdk_wayland_primary_data_source_cancelled,
+};
+
+static gboolean
+gdk_wayland_primary_claim (GdkClipboard *clipboard,
+ GdkContentFormats *formats,
+ gboolean local,
+ GdkContentProvider *content)
+{
+ GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
+
+ if (local)
+ {
+ GdkWaylandDisplay *wdisplay = GDK_WAYLAND_DISPLAY (gdk_clipboard_get_display (clipboard));
+ const char * const *mime_types;
+ gsize i, n_mime_types;
+
+ gdk_wayland_primary_discard_offer (cb);
+ gdk_wayland_primary_discard_source (cb);
+
+ cb->source = gtk_primary_selection_device_manager_create_source (wdisplay->primary_selection_manager);
+ gtk_primary_selection_source_add_listener (cb->source, &primary_source_listener, cb);
+
+ mime_types = gdk_content_formats_get_mime_types (formats, &n_mime_types);
+ for (i = 0; i < n_mime_types; i++)
+ {
+ gtk_primary_selection_source_offer (cb->source, mime_types[i]);
+ }
+
+ gtk_primary_selection_device_set_selection (cb->primary_data_device,
+ cb->source,
+ _gdk_wayland_display_get_serial (wdisplay));
+ }
+
+ return GDK_CLIPBOARD_CLASS (gdk_wayland_primary_parent_class)->claim (clipboard, formats, local, content);
+}
+
+static void
+gdk_wayland_primary_read_async (GdkClipboard *clipboard,
+ GdkContentFormats *formats,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GdkWaylandPrimary *cb = GDK_WAYLAND_PRIMARY (clipboard);
+ GInputStream *stream;
+ const char *mime_type;
+ int pipe_fd[2];
+ GError *error = NULL;
+ GTask *task;
+
+ task = g_task_new (clipboard, cancellable, callback, user_data);
+ g_task_set_priority (task, io_priority);
+ g_task_set_source_tag (task, gdk_wayland_primary_read_async);
+
+ GDK_NOTE (CLIPBOARD, char *s = gdk_content_formats_to_string (formats);
+ g_printerr ("%p: read for %s\n", cb, s);
+ g_free (s); );
+ mime_type = gdk_content_formats_match_mime_type (formats, cb->offer_formats);
+ if (mime_type == NULL)
+ {
+ g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("No compatible transfer format found"));
+ return;
+ }
+ /* offer formats should be empty if we have no offer */
+ g_assert (cb->offer);
+
+ g_task_set_task_data (task, (gpointer) mime_type, NULL);
+
+ if (!g_unix_open_pipe (pipe_fd, FD_CLOEXEC, &error))
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ gtk_primary_selection_offer_receive (cb->offer, mime_type, pipe_fd[1]);
+ stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
+ close (pipe_fd[1]);
+ g_task_return_pointer (task, stream, g_object_unref);
+}
+
+static GInputStream *
+gdk_wayland_primary_read_finish (GdkClipboard *clipboard,
+ const char **out_mime_type,
+ GAsyncResult *result,
+ GError **error)
+{
+ GInputStream *stream;
+ GTask *task;
+
+ g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (clipboard)), NULL);
+ task = G_TASK (result);
+ g_return_val_if_fail (g_task_get_source_tag (task) == gdk_wayland_primary_read_async, NULL);
+
+ stream = g_task_propagate_pointer (task, error);
+
+ if (stream)
+ {
+ if (out_mime_type)
+ *out_mime_type = g_task_get_task_data (task);
+ g_object_ref (stream);
+ }
+ else
+ {
+ if (out_mime_type)
+ *out_mime_type = NULL;
+ }
+
+ return stream;
+}
+
+static void
+gdk_wayland_primary_class_init (GdkWaylandPrimaryClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GdkClipboardClass *clipboard_class = GDK_CLIPBOARD_CLASS (class);
+
+ object_class->finalize = gdk_wayland_primary_finalize;
+
+ clipboard_class->claim = gdk_wayland_primary_claim;
+ clipboard_class->read_async = gdk_wayland_primary_read_async;
+ clipboard_class->read_finish = gdk_wayland_primary_read_finish;
+}
+
+static void
+gdk_wayland_primary_init (GdkWaylandPrimary *cb)
+{
+}
+
+GdkClipboard *
+gdk_wayland_primary_new (GdkWaylandSeat *seat)
+{
+ GdkWaylandDisplay *wdisplay;
+ GdkWaylandPrimary *cb;
+
+ wdisplay = GDK_WAYLAND_DISPLAY (gdk_seat_get_display (GDK_SEAT (seat)));
+
+ cb = g_object_new (GDK_TYPE_WAYLAND_PRIMARY,
+ "display", wdisplay,
+ NULL);
+
+ cb->primary_data_device =
+ gtk_primary_selection_device_manager_get_device (wdisplay->primary_selection_manager,
+ gdk_wayland_seat_get_wl_seat (GDK_SEAT (seat)));
+ gtk_primary_selection_device_add_listener (cb->primary_data_device,
+ &primary_selection_device_listener, cb);
+
+ return GDK_CLIPBOARD (cb);
+}
diff --git a/gdk/wayland/gdkprimary-wayland.h b/gdk/wayland/gdkprimary-wayland.h
new file mode 100644
index 0000000..106ef5e
--- /dev/null
+++ b/gdk/wayland/gdkprimary-wayland.h
@@ -0,0 +1,41 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_PRIMARY_WAYLAND_H__
+#define __GDK_PRIMARY_WAYLAND_H__
+
+#include "gdk/gdkclipboard.h"
+
+#include "gdkseat-wayland.h"
+#include <wayland-client.h>
+#include "gtk-primary-selection-client-protocol.h"
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_WAYLAND_PRIMARY (gdk_wayland_primary_get_type ())
+#define GDK_WAYLAND_PRIMARY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WAYLAND_PRIMARY,
GdkWaylandPrimary))
+#define GDK_IS_WAYLAND_PRIMARY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WAYLAND_PRIMARY))
+
+typedef struct _GdkWaylandPrimary GdkWaylandPrimary;
+
+GType gdk_wayland_primary_get_type (void) G_GNUC_CONST;
+
+GdkClipboard * gdk_wayland_primary_new (GdkWaylandSeat *seat);
+
+G_END_DECLS
+
+#endif /* __GDK_PRIMARY_WAYLAND_H__ */
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 2f99104..ef7f52a 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -184,9 +184,6 @@ struct wl_data_device * gdk_wayland_device_get_data_device (GdkDevice *gdk_devic
void gdk_wayland_device_set_selection (GdkDevice *gdk_device,
struct wl_data_source *source);
-void gdk_wayland_seat_set_primary (GdkSeat *seat,
- struct gtk_primary_selection_source *source);
-
GdkDragContext * gdk_wayland_device_get_drop_context (GdkDevice *gdk_device);
void gdk_wayland_device_unset_touch_grab (GdkDevice *device,
diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c
index 1a20148..cb888f0 100644
--- a/gdk/wayland/gdkselection-wayland.c
+++ b/gdk/wayland/gdkselection-wayland.c
@@ -82,7 +82,6 @@ struct _SelectionData
};
enum {
- ATOM_PRIMARY,
ATOM_DND,
N_ATOMS
};
@@ -100,9 +99,6 @@ struct _GdkWaylandSelection
GArray *source_targets;
GdkAtom requested_target;
- struct gtk_primary_selection_source *primary_source;
- GdkWindow *primary_owner;
-
struct wl_data_source *dnd_source; /* Owned by the GdkDragContext */
GdkWindow *dnd_owner;
};
@@ -307,7 +303,6 @@ gdk_wayland_selection_new (void)
gint i;
/* init atoms */
- atoms[ATOM_PRIMARY] = gdk_atom_intern_static_string ("PRIMARY");
atoms[ATOM_DND] = gdk_atom_intern_static_string ("GdkWaylandSelection");
selection = g_new0 (GdkWaylandSelection, 1);
@@ -348,8 +343,6 @@ gdk_wayland_selection_free (GdkWaylandSelection *selection)
if (selection->stored_selection.fd > 0)
close (selection->stored_selection.fd);
- if (selection->primary_source)
- gtk_primary_selection_source_destroy (selection->primary_source);
if (selection->dnd_source)
wl_data_source_destroy (selection->dnd_source);
@@ -448,41 +441,11 @@ static const struct wl_data_offer_listener data_offer_listener = {
data_offer_action
};
-static void
-primary_offer_offer (void *data,
- struct gtk_primary_selection_offer *gtk_offer,
- const char *type)
-{
- GdkWaylandSelection *selection = data;
- GdkContentFormatsBuilder *builder;
- DataOfferData *info;
-
- info = g_hash_table_lookup (selection->offers, gtk_offer);
-
- if (!info || gdk_content_formats_contain_mime_type (info->targets, type))
- return;
-
- GDK_NOTE (EVENTS,
- g_message ("primary offer offer, offer %p, type = %s", gtk_offer, type));
-
- builder = gdk_content_formats_builder_new ();
- gdk_content_formats_builder_add_formats (builder, info->targets);
- gdk_content_formats_builder_add_mime_type (builder, type);
- gdk_content_formats_unref (info->targets);
- info->targets = gdk_content_formats_builder_free (builder);
-}
-
-static const struct gtk_primary_selection_offer_listener primary_offer_listener = {
- primary_offer_offer,
-};
-
static SelectionData *
selection_lookup_offer_by_atom (GdkWaylandSelection *selection,
GdkAtom selection_atom)
{
- if (selection_atom == atoms[ATOM_PRIMARY])
- return &selection->selections[ATOM_PRIMARY];
- else if (selection_atom == atoms[ATOM_DND])
+ if (selection_atom == atoms[ATOM_DND])
return &selection->selections[ATOM_DND];
else
return NULL;
@@ -508,26 +471,6 @@ gdk_wayland_selection_ensure_offer (GdkDisplay *display,
}
}
-void
-gdk_wayland_selection_ensure_primary_offer (GdkDisplay *display,
- struct gtk_primary_selection_offer *gtk_offer)
-{
- GdkWaylandSelection *selection = gdk_wayland_display_get_selection (display);
- DataOfferData *info;
-
- info = g_hash_table_lookup (selection->offers, gtk_offer);
-
- if (!info)
- {
- info = data_offer_data_new (gtk_offer,
- (GDestroyNotify) gtk_primary_selection_offer_destroy);
- g_hash_table_insert (selection->offers, gtk_offer, info);
- gtk_primary_selection_offer_add_listener (gtk_offer,
- &primary_offer_listener,
- selection);
- }
-}
-
GdkContentFormats *
gdk_wayland_selection_steal_offer (GdkDisplay *display,
gpointer wl_offer)
@@ -1006,55 +949,6 @@ static const struct wl_data_source_listener data_source_listener = {
data_source_action,
};
-static void
-primary_source_send (void *data,
- struct gtk_primary_selection_source *source,
- const char *mime_type,
- int32_t fd)
-{
- GdkWaylandSelection *wayland_selection = data;
-
- GDK_NOTE (EVENTS,
- g_message ("primary source send, source = %p, mime_type = %s, fd = %d",
- source, mime_type, fd));
-
- if (!mime_type || !wayland_selection->primary_owner)
- {
- close (fd);
- return;
- }
-
- if (!gdk_wayland_selection_request_target (wayland_selection,
- wayland_selection->primary_owner,
- atoms[ATOM_PRIMARY],
- gdk_atom_intern (mime_type, FALSE),
- fd))
- gdk_wayland_selection_check_write (wayland_selection);
-}
-
-static void
-primary_source_cancelled (void *data,
- struct gtk_primary_selection_source *source)
-{
- GdkDisplay *display;
- GdkAtom atom;
-
- GDK_NOTE (EVENTS,
- g_message ("primary source cancelled, source = %p", source));
-
- display = gdk_display_get_default ();
-
- atom = atoms[ATOM_PRIMARY];
- emit_selection_clear (display, atom);
- gdk_selection_owner_set (NULL, atom, GDK_CURRENT_TIME, TRUE);
- gdk_wayland_selection_unset_data_source (display, atom);
-}
-
-static const struct gtk_primary_selection_source_listener primary_source_listener = {
- primary_source_send,
- primary_source_cancelled,
-};
-
struct wl_data_source *
gdk_wayland_selection_get_data_source (GdkWindow *owner,
GdkAtom selection)
@@ -1070,18 +964,6 @@ gdk_wayland_selection_get_data_source (GdkWindow *owner,
(!owner || owner == wayland_selection->dnd_owner))
return wayland_selection->dnd_source;
}
- else if (selection == atoms[ATOM_PRIMARY])
- {
- if (wayland_selection->primary_source &&
- (!owner || owner == wayland_selection->primary_owner))
- return (gpointer) wayland_selection->primary_source;
-
- if (wayland_selection->primary_source)
- {
- gtk_primary_selection_source_destroy (wayland_selection->primary_source);
- wayland_selection->primary_source = NULL;
- }
- }
else
return NULL;
@@ -1090,28 +972,13 @@ gdk_wayland_selection_get_data_source (GdkWindow *owner,
display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (owner));
- if (selection == atoms[ATOM_PRIMARY])
- {
- if (display_wayland->primary_selection_manager)
- {
- source = gtk_primary_selection_device_manager_create_source
(display_wayland->primary_selection_manager);
- gtk_primary_selection_source_add_listener (source,
- &primary_source_listener,
- wayland_selection);
- }
- }
- else
- {
- source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
- wl_data_source_add_listener (source,
- &data_source_listener,
- wayland_selection);
- }
+ source = wl_data_device_manager_create_data_source (display_wayland->data_device_manager);
+ wl_data_source_add_listener (source,
+ &data_source_listener,
+ wayland_selection);
if (selection == atoms[ATOM_DND])
wayland_selection->dnd_source = source;
- else if (selection == atoms[ATOM_PRIMARY])
- wayland_selection->primary_source = source;
return source;
}
@@ -1122,19 +989,7 @@ gdk_wayland_selection_unset_data_source (GdkDisplay *display,
{
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
- if (selection == atoms[ATOM_PRIMARY])
- {
- GdkSeat *seat = gdk_display_get_default_seat (display);
-
- gdk_wayland_seat_set_primary (seat, NULL);
-
- if (wayland_selection->primary_source)
- {
- gtk_primary_selection_source_destroy (wayland_selection->primary_source);
- wayland_selection->primary_source = NULL;
- }
- }
- else if (selection == atoms[ATOM_DND])
+ if (selection == atoms[ATOM_DND])
{
wayland_selection->dnd_source = NULL;
}
@@ -1146,9 +1001,7 @@ _gdk_wayland_display_get_selection_owner (GdkDisplay *display,
{
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
- if (selection == atoms[ATOM_PRIMARY])
- return wayland_selection->primary_owner;
- else if (selection == atoms[ATOM_DND])
+ if (selection == atoms[ATOM_DND])
return wayland_selection->dnd_owner;
return NULL;
@@ -1163,12 +1016,7 @@ _gdk_wayland_display_set_selection_owner (GdkDisplay *display,
{
GdkWaylandSelection *wayland_selection = gdk_wayland_display_get_selection (display);
- if (selection == atoms[ATOM_PRIMARY])
- {
- wayland_selection->primary_owner = owner;
- return TRUE;
- }
- else if (selection == atoms[ATOM_DND])
+ if (selection == atoms[ATOM_DND])
{
wayland_selection->dnd_owner = owner;
return TRUE;
@@ -1311,10 +1159,9 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
return;
}
- if (selection != atoms[ATOM_PRIMARY])
- wl_data_offer_accept (offer,
- _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
- mimetype);
+ wl_data_offer_accept (offer,
+ _gdk_wayland_display_get_serial (GDK_WAYLAND_DISPLAY (display)),
+ mimetype);
}
buffer_data = g_hash_table_lookup (selection_data->buffers, target);
@@ -1336,10 +1183,7 @@ _gdk_wayland_display_convert_selection (GdkDisplay *display,
{
g_unix_open_pipe (pipe_fd, FD_CLOEXEC, NULL);
- if (selection == atoms[ATOM_PRIMARY])
- gtk_primary_selection_offer_receive (offer, mimetype, pipe_fd[1]);
- else
- wl_data_offer_receive (offer, mimetype, pipe_fd[1]);
+ wl_data_offer_receive (offer, mimetype, pipe_fd[1]);
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
close (pipe_fd[1]);
@@ -1501,14 +1345,6 @@ gdk_wayland_display_add_selection_targets (GdkDisplay *display,
wl_data_source_offer (data_source, mimetype);
g_free (mimetype);
}
-
- if (selection == atoms[ATOM_PRIMARY])
- {
- GdkSeat *seat;
-
- seat = gdk_display_get_default_seat (display);
- gdk_wayland_seat_set_primary (seat, data_source);
- }
}
void
diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build
index c395631..fec3d2c 100644
--- a/gdk/wayland/meson.build
+++ b/gdk/wayland/meson.build
@@ -9,6 +9,7 @@ gdk_wayland_sources = files([
'gdkglcontext-wayland.c',
'gdkkeys-wayland.c',
'gdkmonitor-wayland.c',
+ 'gdkprimary-wayland.c',
'gdkselection-wayland.c',
'gdkvulkancontext-wayland.c',
'gdkwindow-wayland.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]