Fix Mac crash when creating fullscreen window introduced in 9d43403e9fc5.
authorJørgen P. Tjernø <jorgen@valvesoftware.com>
Mon, 22 Apr 2013 18:14:26 -0700
changeset 70875639ac726076
parent 7086 141ffce8bb59
child 7088 664d8532219b
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
     1.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Mon Apr 22 15:24:35 2013 -0700
     1.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Apr 22 18:14:26 2013 -0700
     1.3 @@ -50,6 +50,8 @@
     1.4      NSView *view = [window contentView];
     1.5  
     1.6      _data = data;
     1.7 +    observingVisible = YES;
     1.8 +    wasVisible = [window isVisible];
     1.9  
    1.10      center = [NSNotificationCenter defaultCenter];
    1.11  
    1.12 @@ -90,6 +92,10 @@
    1.13                          change:(NSDictionary *)change
    1.14                         context:(void *)context
    1.15  {
    1.16 +    if (!observingVisible) {
    1.17 +        return;
    1.18 +    }
    1.19 +
    1.20      if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) {
    1.21          int newVisibility = [[change objectForKey:@"new"] intValue];
    1.22          if (newVisibility) {
    1.23 @@ -100,6 +106,27 @@
    1.24      }
    1.25  }
    1.26  
    1.27 +-(void) pauseVisibleObservation
    1.28 +{
    1.29 +    observingVisible = NO;
    1.30 +    wasVisible = [_data->nswindow isVisible];
    1.31 +}
    1.32 +
    1.33 +-(void) resumeVisibleObservation
    1.34 +{
    1.35 +    BOOL isVisible = [_data->nswindow isVisible];
    1.36 +    observingVisible = YES;
    1.37 +    if (wasVisible != isVisible) {
    1.38 +        if (isVisible) {
    1.39 +            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
    1.40 +        } else {
    1.41 +            SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
    1.42 +        }
    1.43 +
    1.44 +        wasVisible = isVisible;
    1.45 +    }
    1.46 +}
    1.47 +
    1.48  - (void)close
    1.49  {
    1.50      NSNotificationCenter *center;
    1.51 @@ -785,10 +812,13 @@
    1.52  Cocoa_ShowWindow(_THIS, SDL_Window * window)
    1.53  {
    1.54      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    1.55 -    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
    1.56 +    SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
    1.57 +    NSWindow *nswindow = windowData->nswindow;
    1.58  
    1.59      if (![nswindow isMiniaturized]) {
    1.60 +        [windowData->listener pauseVisibleObservation];
    1.61          [nswindow makeKeyAndOrderFront:nil];
    1.62 +        [windowData->listener resumeVisibleObservation];
    1.63      }
    1.64      [pool release];
    1.65  }
    1.66 @@ -807,9 +837,13 @@
    1.67  Cocoa_RaiseWindow(_THIS, SDL_Window * window)
    1.68  {
    1.69      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    1.70 -    NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
    1.71 +    SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata);
    1.72 +    NSWindow *nswindow = windowData->nswindow;
    1.73  
    1.74 +    [windowData->listener pauseVisibleObservation];
    1.75      [nswindow makeKeyAndOrderFront:nil];
    1.76 +    [windowData->listener resumeVisibleObservation];
    1.77 +
    1.78      [pool release];
    1.79  }
    1.80  
    1.81 @@ -960,7 +994,10 @@
    1.82          [nswindow setLevel:kCGNormalWindowLevel];
    1.83      }
    1.84  #endif
    1.85 +
    1.86 +    [data->listener pauseVisibleObservation];
    1.87      [nswindow makeKeyAndOrderFront:nil];
    1.88 +    [data->listener resumeVisibleObservation];
    1.89  
    1.90      if (window == _this->current_glwin) {
    1.91          [((NSOpenGLContext *) _this->current_glctx) update];