diff options
author | Max <post@wickenrode.com> | 2014-11-11 02:47:32 +0100 |
---|---|---|
committer | Max <post@wickenrode.com> | 2014-11-11 02:47:32 +0100 |
commit | 69ca4afe9ba4c9c710b69e4d22d32d22a007c8a9 (patch) | |
tree | c8beabbf65afbaa3afa6dff27e4a9151a2015909 | |
parent | 6d48720a8279e7e97e9a225aab34c0688abd8e00 (diff) | |
download | sequelpro-69ca4afe9ba4c9c710b69e4d22d32d22a007c8a9.tar.gz sequelpro-69ca4afe9ba4c9c710b69e4d22d32d22a007c8a9.tar.bz2 sequelpro-69ca4afe9ba4c9c710b69e4d22d32d22a007c8a9.zip |
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.
-rw-r--r-- | Source/SPDatabaseDocument.h | 1 | ||||
-rw-r--r-- | Source/SPDatabaseDocument.m | 14 | ||||
-rw-r--r-- | Source/SPUserManager.h | 8 | ||||
-rw-r--r-- | Source/SPUserManager.m | 28 |
4 files changed, 38 insertions, 13 deletions
diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h index a67619e8..0cd485b9 100644 --- a/Source/SPDatabaseDocument.h +++ b/Source/SPDatabaseDocument.h @@ -427,7 +427,6 @@ - (void)saveConnectionPanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; - (BOOL)saveDocumentWithFilePath:(NSString *)fileName inBackground:(BOOL)saveInBackground onlyPreferences:(BOOL)saveOnlyPreferences contextInfo:(NSDictionary*)contextInfo; -- (void)userManagerSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context; - (void)setIsSavedInBundle:(BOOL)savedInBundle; - (void)setFileURL:(NSURL *)fileURL; - (void)connect; diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 9a736f90..b8d6dd83 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -2483,16 +2483,10 @@ static NSString *SPAlterDatabaseAction = @"SPAlterDatabase"; return; } - [NSApp beginSheet:[userManagerInstance window] - modalForWindow:parentWindow - modalDelegate:self - didEndSelector:@selector(userManagerSheetDidEnd:returnCode:contextInfo:) - contextInfo:nil]; -} - -- (void)userManagerSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context -{ - [userManagerInstance release], userManagerInstance = nil; + [userManagerInstance beginSheetModalForWindow:parentWindow + completionHandler:^(){ + [userManagerInstance release], userManagerInstance = nil; + }]; } /** diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h index 425c13a6..0058620a 100644 --- a/Source/SPUserManager.h +++ b/Source/SPUserManager.h @@ -124,4 +124,12 @@ - (BOOL)grantPrivilegesToUser:(NSManagedObject *)user; - (BOOL)grantDbPrivilegesWithPrivilege:(NSManagedObject *)user; +// External +/** + * Display the user manager as a sheet attached to a chosen window + * @param docWindow The parent window. + * @param callback A callback that will be called once the window is closed again. Can be NULL. + */ +- (void)beginSheetModalForWindow:(NSWindow *)docWindow completionHandler:(void (^)())callback; + @end diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m index fecb05e0..3ac9e5de 100644 --- a/Source/SPUserManager.m +++ b/Source/SPUserManager.m @@ -61,6 +61,7 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; - (void)_setSchemaPrivValues:(NSArray *)objects enabled:(BOOL)enabled; - (void)_initializeAvailablePrivs; - (void)_renameUserFrom:(NSString *)originalUser host:(NSString *)originalHost to:(NSString *)newUser host:(NSString *)newHost; +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context; @end @@ -471,6 +472,31 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; return managedObjectContext; } +- (void)beginSheetModalForWindow:(NSWindow *)docWindow completionHandler:(void (^)())callback +{ + //copy block from stack to heap, otherwise it wouldn't live long enough to be invoked later. + void *heapCallback = callback? Block_copy(callback) : NULL; + + [NSApp beginSheet:[self window] + modalForWindow:docWindow + modalDelegate:self + didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo:heapCallback]; +} + +- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context +{ + //[NSApp endSheet...] does not close the window + [[self window] orderOut:self]; + //notify delegate + if(context) { + void (^callback)() = context; + //directly invoking callback would risk that we are dealloc'd while still in this run loop iteration. + dispatch_async(dispatch_get_main_queue(), callback); + Block_release(callback); + } +} + #pragma mark - #pragma mark General IBAction methods @@ -489,7 +515,6 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; // Close sheet [NSApp endSheet:[self window] returnCode:0]; - [[self window] orderOut:self]; } /** @@ -539,7 +564,6 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; // Otherwise, close the sheet [NSApp endSheet:[self window] returnCode:0]; - [[self window] orderOut:self]; } /** |