Skip to content
Permalink
Browse files

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.  :)
  • Loading branch information
icculus committed Mar 22, 2015
1 parent 49f33b4 commit b42c2597520793465696f2a82b48480d47c5ad4d
Showing with 63 additions and 26 deletions.
  1. +63 −6 src/video/cocoa/SDL_cocoaevents.m
  2. +0 −20 src/video/cocoa/SDL_cocoawindow.m
@@ -66,28 +66,85 @@ - (id)init
{
self = [super init];
if (self) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

seenFirstActivate = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(focusSomeWindow:)
name:NSApplicationDidBecomeActiveNotification
object:nil];

[center addObserver:self
selector:@selector(windowWillClose:)
name:NSWindowWillCloseNotification
object:nil];

[center addObserver:self
selector:@selector(focusSomeWindow:)
name:NSApplicationDidBecomeActiveNotification
object:nil];
}

return self;
}

- (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];
}

- (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
{
/* HACK: Ignore the first call. The application gets a
* applicationDidBecomeActive: a little bit after the first window is
* 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) {
seenFirstActivate = YES;
@@ -374,7 +374,6 @@ - (void)close
NSNotificationCenter *center;
NSWindow *window = _data->nswindow;
NSView *view = [window contentView];
NSArray *windows = nil;

center = [NSNotificationCenter defaultCenter];

@@ -402,25 +401,6 @@ - (void)close
if ([view nextResponder] == self) {
[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

0 comments on commit b42c259

Please sign in to comment.