[gtk+/composite-templates] wayland: don't wipe clipboard on any change coming from the same owner.
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/composite-templates] wayland: don't wipe clipboard on any change coming from the same owner.
- Date: Thu, 26 Jul 2012 11:52:37 +0000 (UTC)
commit f38df7acb6c6a136b88fcf9bfca868eedf5c3225
Author: Josà Dapena Paz <jdapena igalia com>
Date: Mon Jul 16 15:49:51 2012 +0200
wayland: don't wipe clipboard on any change coming from the same owner.
We now support independent selection and primary clipboards, and avoid
wiping clipboard on modifying its contents from the same owner. This fixes
most of the interaction issues with clipboard and selection.
Signed-off-by: Rob Bradford <rob linux intel com>
gtk/gtkclipboard-wayland.c | 126 ++++++++++++++++++++++++++++++++++----------
1 files changed, 98 insertions(+), 28 deletions(-)
---
diff --git a/gtk/gtkclipboard-wayland.c b/gtk/gtkclipboard-wayland.c
index 256013b..ef8366e 100644
--- a/gtk/gtkclipboard-wayland.c
+++ b/gtk/gtkclipboard-wayland.c
@@ -48,6 +48,8 @@ struct _GtkClipboard
GObject *owner;
GdkDisplay *display;
+ GdkAtom selection;
+
SetContentClosure *last_closure;
};
@@ -122,34 +124,68 @@ gtk_clipboard_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-GtkClipboard *
-gtk_clipboard_get_for_display (GdkDisplay *display,
- GdkAtom selection)
+static void
+clipboard_display_closed (GdkDisplay *display,
+ gboolean is_error,
+ GtkClipboard *clipboard)
{
- GtkClipboard *clipboard;
+ GSList *clipboards;
+
+ clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
+ g_object_run_dispose (G_OBJECT (clipboard));
+ clipboards = g_slist_remove (clipboards, clipboard);
+ g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
+ g_object_unref (clipboard);
+}
+
+static GtkClipboard *
+clipboard_peek (GdkDisplay *display,
+ GdkAtom selection,
+ gboolean only_if_exists)
+{
+ GtkClipboard *clipboard = NULL;
+ GSList *clipboards;
+ GSList *tmp_list;
if (selection == GDK_NONE)
selection = GDK_SELECTION_CLIPBOARD;
- if (selection != GDK_SELECTION_CLIPBOARD)
- {
- g_warning (G_STRLOC ": Only able to create clipboard for CLIPBOARD");
- }
+ clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
- selection = GDK_SELECTION_CLIPBOARD;
-
- clipboard = g_object_get_data (G_OBJECT (display), "gtk-clipboard");
+ tmp_list = clipboards;
+ while (tmp_list)
+ {
+ clipboard = tmp_list->data;
+ if (clipboard->selection == selection)
+ break;
- if (clipboard)
- return clipboard;
+ tmp_list = tmp_list->next;
+ }
- clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
- clipboard->display = display;
+ if (!tmp_list && !only_if_exists)
+ {
+ clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
+ clipboard->selection = selection;
+ clipboard->display = display;
+
+ clipboards = g_slist_prepend (clipboards, clipboard);
+ g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
+ g_signal_connect (display, "closed",
+ G_CALLBACK (clipboard_display_closed), clipboard);
+ gdk_display_request_selection_notification (display, selection);
+ }
+
+ return clipboard;
+}
- g_object_set_data (G_OBJECT (display), "gtk-clipboard", clipboard);
+GtkClipboard *
+gtk_clipboard_get_for_display (GdkDisplay *display,
+ GdkAtom selection)
+{
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ g_return_val_if_fail (!gdk_display_is_closed (display), NULL);
- /* TODO: Need to connect to display closed to free this */
- return clipboard;
+ return clipboard_peek (display, selection, FALSE);
}
GtkClipboard *
@@ -164,6 +200,7 @@ struct _SetContentClosure {
GtkClipboardGetFunc get_func;
GtkClipboardClearFunc clear_func;
guint info;
+ gboolean have_owner;
gpointer userdata;
GtkTargetPair *targets;
gint n_targets;
@@ -203,6 +240,21 @@ _offer_cb (GdkDevice *device,
return (gchar *)selection_data.data;
}
+static void
+clipboard_owner_destroyed (gpointer data,
+ GObject *owner)
+{
+ GtkClipboard *clipboard = (GtkClipboard *) data;
+ SetContentClosure *last_closure = clipboard->last_closure;
+
+ last_closure->userdata = NULL;
+ last_closure->get_func = NULL;
+ last_closure->clear_func = NULL;
+ last_closure->have_owner = FALSE;
+
+ gtk_clipboard_clear (clipboard);
+}
+
static gboolean
gtk_clipboard_set_contents (GtkClipboard *clipboard,
const GtkTargetEntry *targets,
@@ -216,21 +268,34 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
GdkDevice *device;
gint i;
gchar **mimetypes;
- SetContentClosure *closure;
-
- gtk_clipboard_clear (clipboard);
+ SetContentClosure *closure, *last_closure;
+
+ last_closure = clipboard->last_closure;
+ if (!last_closure ||
+ (!last_closure->have_owner && have_owner) ||
+ (last_closure->userdata != user_data)) {
+ gtk_clipboard_clear (clipboard);
+
+ closure = g_new0 (SetContentClosure, 1);
+ closure->clipboard = clipboard;
+ closure->userdata = user_data;
+ closure->have_owner = have_owner;
+
+ if (have_owner)
+ g_object_weak_ref (G_OBJECT (user_data), clipboard_owner_destroyed, clipboard);
+ } else {
+ closure = last_closure;
+ g_free (closure->targets);
+ }
- device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
- device = gdk_device_manager_get_client_pointer (device_manager);
-
- closure = g_new0 (SetContentClosure, 1);
- closure->clipboard = clipboard;
closure->get_func = get_func;
closure->clear_func = clear_func;
- closure->userdata = user_data;
closure->targets = g_new0 (GtkTargetPair, n_targets);
closure->n_targets = n_targets;
+ device_manager = gdk_display_get_device_manager (gdk_display_get_default ());
+ device = gdk_device_manager_get_client_pointer (device_manager);
+
mimetypes = g_new (gchar *, n_targets);
for (i = 0; i < n_targets; i++)
@@ -318,7 +383,12 @@ gtk_clipboard_clear (GtkClipboard *clipboard)
clipboard->last_closure->userdata);
}
- /* TODO: Free last closure */
+ if (clipboard->last_closure->have_owner)
+ g_object_weak_unref (G_OBJECT (clipboard->last_closure->userdata),
+ clipboard_owner_destroyed, clipboard);
+ g_free (clipboard->last_closure->targets);
+ g_free (clipboard->last_closure);
+
clipboard->last_closure = NULL;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]