We must not release the GtkClipboardOwner in pasteboardChangedOwner
becaue we don't own a reference to ourselves (NSPasteboard does).
Instead, release the owner right after setting it, transferring
ownership to NSPasteboard
Also, fix repeated setting of the same owner by keeping the
owner around in GtkCLipboard, and re-use it if "user_data"
doesn't change. To avoid clipboard_unset()ting our own contents
in the process, add an ugly "setting_same_owner" boolean to
GtkClipboardOwner, set it during re-setting the same owner,
and avoid calling clipboard_unset() from pasteboardChangedOwner
if it's TRUE.
(cherry picked from commit
4a8df7a33c298d22bf78b947d0e861fc03ec70e1)
+@interface GtkClipboardOwner : NSObject {
+ GtkClipboard *clipboard;
+ gboolean setting_same_owner;
+}
+
+@end
+
typedef struct _GtkClipboardClass GtkClipboardClass;
struct _GtkClipboard
typedef struct _GtkClipboardClass GtkClipboardClass;
struct _GtkClipboard
GObject parent_instance;
NSPasteboard *pasteboard;
GObject parent_instance;
NSPasteboard *pasteboard;
+ GtkClipboardOwner *owner;
NSInteger change_count;
GdkAtom selection;
NSInteger change_count;
GdkAtom selection;
GdkAtom selection,
gboolean only_if_exists);
GdkAtom selection,
gboolean only_if_exists);
-@interface GtkClipboardOwner : NSObject {
- GtkClipboard *clipboard;
-}
-
-@end
-
@implementation GtkClipboardOwner
-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
@implementation GtkClipboardOwner
-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
{
*/
- (void)pasteboardChangedOwner:(NSPasteboard *)sender
{
*/
- (void)pasteboardChangedOwner:(NSPasteboard *)sender
{
- clipboard_unset (clipboard);
-
- [self release];
+ if (! setting_same_owner)
+ clipboard_unset (clipboard);
}
- (id)initWithClipboard:(GtkClipboard *)aClipboard
}
- (id)initWithClipboard:(GtkClipboard *)aClipboard
if (self)
{
clipboard = aClipboard;
if (self)
{
clipboard = aClipboard;
+ setting_same_owner = FALSE;
NSSet *types;
NSAutoreleasePool *pool;
NSSet *types;
NSAutoreleasePool *pool;
- pool = [[NSAutoreleasePool alloc] init];
-
- owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
-
if (!(clipboard->have_owner && have_owner) ||
clipboard->user_data != user_data)
{
if (!(clipboard->have_owner && have_owner) ||
clipboard->user_data != user_data)
{
clipboard->user_data != user_data)
{
(*clear_func) (clipboard, user_data);
clipboard->user_data != user_data)
{
(*clear_func) (clipboard, user_data);
+ pool = [[NSAutoreleasePool alloc] init];
+
+ types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
+
/* call declareTypes before setting the clipboard members because
* declareTypes might clear the 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];
+ if (user_data && user_data == clipboard->user_data)
+ {
+ owner = [clipboard->owner retain];
+
+ owner->setting_same_owner = TRUE;
+ clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
+ owner: owner];
+ owner->setting_same_owner = FALSE;
+ }
+ else
+ {
+ owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
+
+ clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
+ owner: owner];
+ }
+
+ [owner release];
[types release];
[pool release];
[types release];
[pool release];
+ clipboard->owner = owner;
clipboard->user_data = user_data;
clipboard->have_owner = have_owner;
if (have_owner)
clipboard->user_data = user_data;
clipboard->have_owner = have_owner;
if (have_owner)
clipboard->n_storable_targets = -1;
g_free (clipboard->storable_targets);
clipboard->storable_targets = NULL;
clipboard->n_storable_targets = -1;
g_free (clipboard->storable_targets);
clipboard->storable_targets = NULL;
+
+ clipboard->owner = NULL;
clipboard->get_func = NULL;
clipboard->clear_func = NULL;
clipboard->user_data = NULL;
clipboard->get_func = NULL;
clipboard->clear_func = NULL;
clipboard->user_data = NULL;