aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2014-11-11 02:47:32 +0100
committerMax <post@wickenrode.com>2014-11-11 02:47:32 +0100
commit69ca4afe9ba4c9c710b69e4d22d32d22a007c8a9 (patch)
treec8beabbf65afbaa3afa6dff27e4a9151a2015909
parent6d48720a8279e7e97e9a225aab34c0688abd8e00 (diff)
downloadsequelpro-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.h1
-rw-r--r--Source/SPDatabaseDocument.m14
-rw-r--r--Source/SPUserManager.h8
-rw-r--r--Source/SPUserManager.m28
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];
}
/**