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. :)main
parent
49f33b41a7
commit
b42c259752
|
@ -66,11 +66,19 @@
|
|||
{
|
||||
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;
|
||||
|
@ -78,16 +86,65 @@
|
|||
|
||||
- (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 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
NSNotificationCenter *center;
|
||||
NSWindow *window = _data->nswindow;
|
||||
NSView *view = [window contentView];
|
||||
NSArray *windows = nil;
|
||||
|
||||
center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
|
@ -402,25 +401,6 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue