Ticket #37330: gtkclipboard-quartz.patch

File gtkclipboard-quartz.patch, 4.6 KB (added by help@…, 11 years ago)

fixed patch for described issue

  • gtk/gtkclipboard-quartz.c

    From 4a8df7a33c298d22bf78b947d0e861fc03ec70e1 Mon Sep 17 00:00:00 2001
    From: Michael Natterer <mitch@lanedo.com>
    Date: Fri, 07 Dec 2012 11:19:52 +0000
    Subject: quartz: fix crash in the recent clipboard "fix", and really fix it
    
    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.
    ---
    (limited to 'gtk/gtkclipboard-quartz.c')
    
    diff --git gtk/gtkclipboard-quartz.c gtk/gtkclipboard-quartz.c
    index 743f037..14b0974 100644
    enum { 
    3939  LAST_SIGNAL
    4040};
    4141
     42@interface GtkClipboardOwner : NSObject {
     43  GtkClipboard *clipboard;
     44  @public
     45  gboolean setting_same_owner;
     46}
     47
     48@end
     49
    4250typedef struct _GtkClipboardClass GtkClipboardClass;
    4351
    4452struct _GtkClipboard
    struct _GtkClipboard 
    4654  GObject parent_instance;
    4755
    4856  NSPasteboard *pasteboard;
     57  GtkClipboardOwner *owner;
    4958  NSInteger change_count;
    5059
    5160  GdkAtom selection;
    static GtkClipboard *clipboard_peek (GdkDisplay *display, 
    8896                                           GdkAtom           selection,
    8997                                           gboolean          only_if_exists);
    9098
    91 @interface GtkClipboardOwner : NSObject {
    92   GtkClipboard *clipboard;
    93 }
    94 
    95 @end
    96 
    9799@implementation GtkClipboardOwner
    98100-(void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type
    99101{
    static GtkClipboard *clipboard_peek (GdkDisplay *display, 
    132135 */
    133136- (void)pasteboardChangedOwner:(NSPasteboard *)sender
    134137{
    135   clipboard_unset (clipboard);
    136 
    137   [self release];
     138  if (! setting_same_owner)
     139    clipboard_unset (clipboard);
    138140}
    139141
    140142- (id)initWithClipboard:(GtkClipboard *)aClipboard
    static GtkClipboard *clipboard_peek (GdkDisplay *display, 
    144146  if (self)
    145147    {
    146148      clipboard = aClipboard;
     149      setting_same_owner = FALSE;
    147150    }
    148151
    149152  return self;
    gtk_clipboard_set_contents (GtkClipboard *clipboard, 
    334337  NSSet *types;
    335338  NSAutoreleasePool *pool;
    336339
    337   pool = [[NSAutoreleasePool alloc] init];
    338 
    339   owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
    340 
    341340  if (!(clipboard->have_owner && have_owner) ||
    342341      clipboard->user_data != user_data)
    343342    {
    gtk_clipboard_set_contents (GtkClipboard *clipboard, 
    352351              clipboard->user_data != user_data)
    353352            {
    354353              (*clear_func) (clipboard, user_data);
    355               [pool release];
    356354              return FALSE;
    357355            }
    358356          else
    359357            {
    360               [pool release];
    361358              return TRUE;
    362359            }
    363360        }
    364361    }
    365362
     363  pool = [[NSAutoreleasePool alloc] init];
     364
     365  types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
     366
    366367  /*  call declareTypes before setting the clipboard members because
    367368   *  declareTypes might clear the clipboard
    368369   */
    369   types = _gtk_quartz_target_entries_to_pasteboard_types (targets, n_targets);
    370   clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
    371                                                           owner: owner];
     370  if (user_data && user_data == clipboard->user_data)
     371    {
     372      owner = [clipboard->owner retain];
     373
     374      owner->setting_same_owner = TRUE;
     375      clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
     376                                                              owner: owner];
     377      owner->setting_same_owner = FALSE;
     378    }
     379  else
     380    {
     381      owner = [[GtkClipboardOwner alloc] initWithClipboard:clipboard];
     382
     383      clipboard->change_count = [clipboard->pasteboard declareTypes: [types allObjects]
     384                                                              owner: owner];
     385    }
     386
     387  [owner release];
    372388  [types release];
    373389  [pool release];
    374390
     391  clipboard->owner = owner;
    375392  clipboard->user_data = user_data;
    376393  clipboard->have_owner = have_owner;
    377394  if (have_owner)
    clipboard_unset (GtkClipboard *clipboard) 
    460477  clipboard->n_storable_targets = -1;
    461478  g_free (clipboard->storable_targets);
    462479  clipboard->storable_targets = NULL;
    463      
     480
     481  clipboard->owner = NULL;
    464482  clipboard->get_func = NULL;
    465483  clipboard->clear_func = NULL;
    466484  clipboard->user_data = NULL;