Cocoa: Handle more cases of lost focus when Key window closes (thanks, Alex!).

Sort of fixes Bugzilla #1825 a little more. It's an ongoing effort.  :)
This commit is contained in:
Ryan C. Gordon 2015-03-22 01:25:12 -04:00
parent 49f33b41a7
commit b42c259752
2 changed files with 63 additions and 26 deletions

View File

@ -66,8 +66,16 @@
{ {
self = [super init]; self = [super init];
if (self) { if (self) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
seenFirstActivate = NO; seenFirstActivate = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
[center addObserver:self
selector:@selector(windowWillClose:)
name:NSWindowWillCloseNotification
object:nil];
[center addObserver:self
selector:@selector(focusSomeWindow:) selector:@selector(focusSomeWindow:)
name:NSApplicationDidBecomeActiveNotification name:NSApplicationDidBecomeActiveNotification
object:nil]; object:nil];
@ -78,16 +86,65 @@
- (void)dealloc - (void)dealloc
{ {
[[NSNotificationCenter defaultCenter] removeObserver:self]; NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self name:NSWindowWillCloseNotification object:nil];
[center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
[super dealloc]; [super dealloc];
} }
- (void)windowWillClose:(NSNotification *)notification;
{
NSWindow *win = (NSWindow*)[notification object];
if (![win isKeyWindow]) {
return;
}
/* HACK: Make the next window in the z-order key when the key window is
* closed. The custom event loop and/or windowing code we have seems to
* prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825
*/
/* +[NSApp orderedWindows] never includes the 'About' window, but we still
* want to try its list first since the behavior in other apps is to only
* make the 'About' window key if no other windows are on-screen.
*/
for (NSWindow *window in [NSApp orderedWindows]) {
if (window != win && [window canBecomeKeyWindow]) {
if ([window respondsToSelector:@selector(isOnActiveSpace)]) {
if (![window isOnActiveSpace]) {
continue;
}
}
[window makeKeyAndOrderFront:self];
return;
}
}
/* If a window wasn't found above, iterate through all visible windows
* (including the 'About' window, if it's shown) and make the first one key.
* Note that +[NSWindow windowNumbersWithOptions:] was added in 10.6.
*/
if ([NSWindow respondsToSelector:@selector(windowNumbersWithOptions:)]) {
/* Get all visible windows in the active Space, in z-order. */
for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
if (window && window != win && [window canBecomeKeyWindow]) {
[window makeKeyAndOrderFront:self];
return;
}
}
}
}
- (void)focusSomeWindow:(NSNotification *)aNotification - (void)focusSomeWindow:(NSNotification *)aNotification
{ {
/* HACK: Ignore the first call. The application gets a /* HACK: Ignore the first call. The application gets a
* applicationDidBecomeActive: a little bit after the first window is * applicationDidBecomeActive: a little bit after the first window is
* created, and if we don't ignore it, a window that has been created with * created, and if we don't ignore it, a window that has been created with
* SDL_WINDOW_MINIZED will ~immediately be restored. * SDL_WINDOW_MINIMIZED will ~immediately be restored.
*/ */
if (!seenFirstActivate) { if (!seenFirstActivate) {
seenFirstActivate = YES; seenFirstActivate = YES;

View File

@ -374,7 +374,6 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
NSNotificationCenter *center; NSNotificationCenter *center;
NSWindow *window = _data->nswindow; NSWindow *window = _data->nswindow;
NSView *view = [window contentView]; NSView *view = [window contentView];
NSArray *windows = nil;
center = [NSNotificationCenter defaultCenter]; center = [NSNotificationCenter defaultCenter];
@ -402,25 +401,6 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
if ([view nextResponder] == self) { if ([view nextResponder] == self) {
[view setNextResponder:nil]; [view setNextResponder:nil];
} }
/* Make the next window in the z-order Key. If we weren't the foreground
when closed, this is a no-op.
!!! FIXME: Note that this is a hack, and there are corner cases where
!!! FIXME: this fails (such as the About box). The typical nib+RunLoop
!!! FIXME: handles this for Cocoa apps, but we bypass all that in SDL.
!!! FIXME: We should remove this code when we find a better way to
!!! FIXME: have the system do this for us. See discussion in
!!! FIXME: http://bugzilla.libsdl.org/show_bug.cgi?id=1825
*/
windows = [NSApp orderedWindows];
for (NSWindow *win in windows) {
if (win == window) {
continue;
}
[win makeKeyAndOrderFront:self];
break;
}
} }
- (BOOL)isMoving - (BOOL)isMoving