[gtk+] Bug 626499 - GtkClipboard unnotified on change of OS X pasteboard owner
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] Bug 626499 - GtkClipboard unnotified on change of OS X pasteboard owner
- Date: Tue, 4 Dec 2012 13:42:50 +0000 (UTC)
commit f08fc1274141a0e631687de12246409881ec2454
Author: Michael Natterer <mitch gimp org>
Date: Tue Dec 4 14:31:13 2012 +0100
Bug 626499 - GtkClipboard unnotified on change of OS X pasteboard owner
pasteboardChangedOwner is not called as reliably as we'd want to get it,
so keep track of [pasteboard changeCount] and drop clipboard ownership
when a change happened. Also better unset the clipboard content redundantly
in a few places rather than missing one, and reorder the code in
gtk_clipboard_set_contents() so that the new aggressive unsetting
won't unset the clipboard under our feet when we call
[pasteboard declareTypes].
(cherry picked from commit f2b74db5dcbd28a1e27431f413c66d2a5d50b2bd)
gtk/gtkclipboard-quartz.c | 63 +++++++++++++++++++++++++++++---------------
1 files changed, 41 insertions(+), 22 deletions(-)
---
diff --git a/gtk/gtkclipboard-quartz.c b/gtk/gtkclipboard-quartz.c
index 35ab27b..9a01b7c 100644
--- a/gtk/gtkclipboard-quartz.c
+++ b/gtk/gtkclipboard-quartz.c
@@ -45,6 +45,7 @@ struct _GtkClipboard
GObject parent_instance;
NSPasteboard *pasteboard;
+ NSInteger change_count;
GdkAtom selection;
@@ -76,13 +77,18 @@ struct _GtkClipboardClass
GdkEventOwnerChange *event);
};
+static void gtk_clipboard_class_init (GtkClipboardClass *class);
+static void gtk_clipboard_finalize (GObject *object);
+static void gtk_clipboard_owner_change (GtkClipboard *clipboard,
+ GdkEventOwnerChange *event);
+
+static void clipboard_unset (GtkClipboard *clipboard);
+static GtkClipboard *clipboard_peek (GdkDisplay *display,
+ GdkAtom selection,
+ gboolean only_if_exists);
+
@interface GtkClipboardOwner : NSObject {
GtkClipboard *clipboard;
-
- GtkClipboardGetFunc get_func;
- GtkClipboardClearFunc clear_func;
- gpointer user_data;
-
}
@end
@@ -117,10 +123,15 @@ struct _GtkClipboardClass
}
}
+/* pasteboardChangedOwner is not called immediately, and it's not called
+ * reliably. It is somehow documented in the apple api docs, but the docs
+ * suck and don't really give clear instructions. Therefore we track
+ * changeCount in several places below and clear the clipboard if it
+ * changed.
+ */
- (void)pasteboardChangedOwner:(NSPasteboard *)sender
{
- if (clear_func)
- clear_func (clipboard, user_data);
+ clipboard_unset (clipboard);
[self release];
}
@@ -139,15 +150,6 @@ struct _GtkClipboardClass
@end
-static void gtk_clipboard_class_init (GtkClipboardClass *class);
-static void gtk_clipboard_finalize (GObject *object);
-static void gtk_clipboard_owner_change (GtkClipboard *clipboard,
- GdkEventOwnerChange *event);
-
-static void clipboard_unset (GtkClipboard *clipboard);
-static GtkClipboard *clipboard_peek (GdkDisplay *display,
- GdkAtom selection,
- gboolean only_if_exists);
static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
static GQuark clipboards_owned_key_id = 0;
@@ -360,6 +362,15 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
}
}
+ /* call declareTypes before setting the clipboard members because
+ * declareTypes might clear the clipboard
+ */
+ types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
+ clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
+ owner: owner];
+ [types release];
+ [pool release];
+
clipboard->user_data = user_data;
clipboard->have_owner = have_owner;
if (have_owner)
@@ -371,12 +382,6 @@ gtk_clipboard_set_contents (GtkClipboard *clipboard,
gtk_target_list_unref (clipboard->target_list);
clipboard->target_list = gtk_target_list_new (targets, n_targets);
- types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
-
- [clipboard->pasteboard declareTypes:[types allObjects] owner:owner];
- [types release];
- [pool release];
-
return TRUE;
}
@@ -420,6 +425,12 @@ gtk_clipboard_get_owner (GtkClipboard *clipboard)
{
g_return_val_if_fail (clipboard != NULL, NULL);
+ if (clipboard->change_count < [clipboard->pasteboard changeCount])
+ {
+ clipboard_unset (clipboard);
+ clipboard->change_count = [clipboard->pasteboard changeCount];
+ }
+
if (clipboard->have_owner)
return clipboard->user_data;
else
@@ -473,6 +484,8 @@ clipboard_unset (GtkClipboard *clipboard)
void
gtk_clipboard_clear (GtkClipboard *clipboard)
{
+ clipboard_unset (clipboard);
+
[clipboard->pasteboard declareTypes:nil owner:nil];
}
@@ -656,6 +669,12 @@ gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GtkSelectionData *selection_data = NULL;
+ if (clipboard->change_count < [clipboard->pasteboard changeCount])
+ {
+ clipboard_unset (clipboard);
+ clipboard->change_count = [clipboard->pasteboard changeCount];
+ }
+
if (target == gdk_atom_intern_static_string ("TARGETS"))
{
NSArray *types = [clipboard->pasteboard types];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]