From babe495d7d1d338054a0d682a987d3a553c51ec1 Mon Sep 17 00:00:00 2001 From: "J?rgen P. Tjern?" Date: Mon, 22 Apr 2013 18:14:26 -0700 Subject: [PATCH] Fix Mac crash when creating fullscreen window introduced in 9d43403e9fc5. makeKeyAndOrderFront: was sending three KVO transitions for isVisible, for false -> true, true -> false, and then false -> true. This was causing an infinite recursion. We now suspend monitoring of the KVO before makeKeyAndOrderFront, then resume afterwards and send any changes in isVisible's state. --- src/video/cocoa/SDL_cocoawindow.m | 41 +++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 0ebb3c94a..5e9c599fe 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -50,6 +50,8 @@ - (void)listen:(SDL_WindowData *)data NSView *view = [window contentView]; _data = data; + observingVisible = YES; + wasVisible = [window isVisible]; center = [NSNotificationCenter defaultCenter]; @@ -90,6 +92,10 @@ - (void)observeValueForKeyPath:(NSString *)keyPath change:(NSDictionary *)change context:(void *)context { + if (!observingVisible) { + return; + } + if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) { int newVisibility = [[change objectForKey:@"new"] intValue]; if (newVisibility) { @@ -100,6 +106,27 @@ - (void)observeValueForKeyPath:(NSString *)keyPath } } +-(void) pauseVisibleObservation +{ + observingVisible = NO; + wasVisible = [_data->nswindow isVisible]; +} + +-(void) resumeVisibleObservation +{ + BOOL isVisible = [_data->nswindow isVisible]; + observingVisible = YES; + if (wasVisible != isVisible) { + if (isVisible) { + SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + } else { + SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + } + + wasVisible = isVisible; + } +} + - (void)close { NSNotificationCenter *center; @@ -785,10 +812,13 @@ - (void)rightMouseDown:(NSEvent *)theEvent Cocoa_ShowWindow(_THIS, SDL_Window * window) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData->nswindow; if (![nswindow isMiniaturized]) { + [windowData->listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; + [windowData->listener resumeVisibleObservation]; } [pool release]; } @@ -807,9 +837,13 @@ - (void)rightMouseDown:(NSEvent *)theEvent Cocoa_RaiseWindow(_THIS, SDL_Window * window) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData->nswindow; + [windowData->listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; + [windowData->listener resumeVisibleObservation]; + [pool release]; } @@ -960,7 +994,10 @@ - (void)rightMouseDown:(NSEvent *)theEvent [nswindow setLevel:kCGNormalWindowLevel]; } #endif + + [data->listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; + [data->listener resumeVisibleObservation]; if (window == _this->current_glwin) { [((NSOpenGLContext *) _this->current_glctx) update];