Skip to content

Commit 69ca4af

Browse files
committed
Attempt to fix #1961
Namely this commit changes two things: 1) In the past the user manager window technically was closed after it was released (SPUserManager.m:491): [NSApp endSheet:[self window] returnCode:0]; //-> calls delegate, which calls release [[self window] orderOut:self]; This call order has now been swapped. 2) Because the delegate is invoked directly by NSApp, the release was called before other UI elements had finished their cleanup from orderOut:. The delegate callback is now put on the runloop to give other stuff priority. Requesting QA on this commit.
1 parent 6d48720 commit 69ca4af

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed

Source/SPDatabaseDocument.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,6 @@
427427

428428
- (void)saveConnectionPanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
429429
- (BOOL)saveDocumentWithFilePath:(NSString *)fileName inBackground:(BOOL)saveInBackground onlyPreferences:(BOOL)saveOnlyPreferences contextInfo:(NSDictionary*)contextInfo;
430-
- (void)userManagerSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context;
431430
- (void)setIsSavedInBundle:(BOOL)savedInBundle;
432431
- (void)setFileURL:(NSURL *)fileURL;
433432
- (void)connect;

Source/SPDatabaseDocument.m

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2483,16 +2483,10 @@ - (IBAction)showUserManager:(id)sender
24832483
return;
24842484
}
24852485

2486-
[NSApp beginSheet:[userManagerInstance window]
2487-
modalForWindow:parentWindow
2488-
modalDelegate:self
2489-
didEndSelector:@selector(userManagerSheetDidEnd:returnCode:contextInfo:)
2490-
contextInfo:nil];
2491-
}
2492-
2493-
- (void)userManagerSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context
2494-
{
2495-
[userManagerInstance release], userManagerInstance = nil;
2486+
[userManagerInstance beginSheetModalForWindow:parentWindow
2487+
completionHandler:^(){
2488+
[userManagerInstance release], userManagerInstance = nil;
2489+
}];
24962490
}
24972491

24982492
/**

Source/SPUserManager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,12 @@
124124
- (BOOL)grantPrivilegesToUser:(NSManagedObject *)user;
125125
- (BOOL)grantDbPrivilegesWithPrivilege:(NSManagedObject *)user;
126126

127+
// External
128+
/**
129+
* Display the user manager as a sheet attached to a chosen window
130+
* @param docWindow The parent window.
131+
* @param callback A callback that will be called once the window is closed again. Can be NULL.
132+
*/
133+
- (void)beginSheetModalForWindow:(NSWindow *)docWindow completionHandler:(void (^)())callback;
134+
127135
@end

Source/SPUserManager.m

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ - (NSArray *)_fetchPrivsWithUser:(NSString *)username schema:(NSString *)selecte
6161
- (void)_setSchemaPrivValues:(NSArray *)objects enabled:(BOOL)enabled;
6262
- (void)_initializeAvailablePrivs;
6363
- (void)_renameUserFrom:(NSString *)originalUser host:(NSString *)originalHost to:(NSString *)newUser host:(NSString *)newHost;
64+
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context;
6465

6566
@end
6667

@@ -471,6 +472,31 @@ - (NSManagedObjectContext *)managedObjectContext
471472
return managedObjectContext;
472473
}
473474

475+
- (void)beginSheetModalForWindow:(NSWindow *)docWindow completionHandler:(void (^)())callback
476+
{
477+
//copy block from stack to heap, otherwise it wouldn't live long enough to be invoked later.
478+
void *heapCallback = callback? Block_copy(callback) : NULL;
479+
480+
[NSApp beginSheet:[self window]
481+
modalForWindow:docWindow
482+
modalDelegate:self
483+
didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
484+
contextInfo:heapCallback];
485+
}
486+
487+
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context
488+
{
489+
//[NSApp endSheet...] does not close the window
490+
[[self window] orderOut:self];
491+
//notify delegate
492+
if(context) {
493+
void (^callback)() = context;
494+
//directly invoking callback would risk that we are dealloc'd while still in this run loop iteration.
495+
dispatch_async(dispatch_get_main_queue(), callback);
496+
Block_release(callback);
497+
}
498+
}
499+
474500
#pragma mark -
475501
#pragma mark General IBAction methods
476502

@@ -489,7 +515,6 @@ - (IBAction)doCancel:(id)sender
489515

490516
// Close sheet
491517
[NSApp endSheet:[self window] returnCode:0];
492-
[[self window] orderOut:self];
493518
}
494519

495520
/**
@@ -539,7 +564,6 @@ - (IBAction)doApply:(id)sender
539564

540565
// Otherwise, close the sheet
541566
[NSApp endSheet:[self window] returnCode:0];
542-
[[self window] orderOut:self];
543567
}
544568

545569
/**

0 commit comments

Comments
 (0)