From 7cf76ffbe04fadd49d94e895823c5c26a6489ef3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 11 Nov 2013 21:21:18 -0800 Subject: [PATCH] Fixed assertion failure when minimizing a fullscreen window. --- src/video/cocoa/SDL_cocoawindow.h | 18 ++++++---- src/video/cocoa/SDL_cocoawindow.m | 58 +++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index dbe592a780e32..bbb5b6cf9c18a 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -27,6 +27,14 @@ typedef struct SDL_WindowData SDL_WindowData; +typedef enum +{ + PENDING_OPERATION_NONE, + PENDING_OPERATION_ENTER_FULLSCREEN, + PENDING_OPERATION_LEAVE_FULLSCREEN, + PENDING_OPERATION_MINIMIZE +} PendingWindowOperation; + @interface Cocoa_WindowListener : NSResponder { SDL_WindowData *_data; BOOL observingVisible; @@ -34,19 +42,15 @@ typedef struct SDL_WindowData SDL_WindowData; BOOL wasVisible; BOOL isFullscreen; BOOL inFullscreenTransition; - - enum - { - PENDING_TRANSITION_NONE, - PENDING_TRANSITION_ENTER_FULLSCREEN, - PENDING_TRANSITION_LEAVE_FULLSCREEN - } pendingFullscreenTransition; + PendingWindowOperation pendingWindowOperation; } -(void) listen:(SDL_WindowData *) data; -(void) pauseVisibleObservation; -(void) resumeVisibleObservation; -(BOOL) setFullscreenState:(BOOL) state; +-(BOOL) isInFullscreenTransition; +-(void) addPendingWindowOperation:(PendingWindowOperation) operation; -(void) close; /* Window delegate functionality */ diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 5ae119fc8e9ad..1e5c24fdf5dc9 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -103,7 +103,7 @@ - (void)listen:(SDL_WindowData *)data wasVisible = [window isVisible]; isFullscreen = NO; inFullscreenTransition = NO; - pendingFullscreenTransition = PENDING_TRANSITION_NONE; + pendingWindowOperation = PENDING_OPERATION_NONE; center = [NSNotificationCenter defaultCenter]; @@ -199,7 +199,7 @@ -(BOOL) setFullscreenState:(BOOL) state; return NO; } - pendingFullscreenTransition = PENDING_TRANSITION_NONE; + pendingWindowOperation = PENDING_OPERATION_NONE; /* We can enter new style fullscreen mode for "fullscreen desktop" */ if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { @@ -221,9 +221,9 @@ -(BOOL) setFullscreenState:(BOOL) state; if (inFullscreenTransition) { if (state) { - pendingFullscreenTransition = PENDING_TRANSITION_ENTER_FULLSCREEN; + [self addPendingWindowOperation:PENDING_OPERATION_ENTER_FULLSCREEN]; } else { - pendingFullscreenTransition = PENDING_TRANSITION_LEAVE_FULLSCREEN; + [self addPendingWindowOperation:PENDING_OPERATION_LEAVE_FULLSCREEN]; } return YES; } @@ -232,6 +232,16 @@ -(BOOL) setFullscreenState:(BOOL) state; return YES; } +-(BOOL) isInFullscreenTransition +{ + return inFullscreenTransition; +} + +-(void) addPendingWindowOperation:(PendingWindowOperation) operation +{ + pendingWindowOperation = operation; +} + - (void)close { NSNotificationCenter *center; @@ -328,8 +338,10 @@ - (void)windowDidMove:(NSNotification *)aNotification - (void)windowDidResize:(NSNotification *)aNotification { + SDL_Window *window = _data->window; + NSWindow *nswindow = _data->nswindow; int x, y, w, h; - NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]]; + NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; ConvertNSRect(&rect); x = (int)rect.origin.x; y = (int)rect.origin.y; @@ -341,22 +353,22 @@ - (void)windowDidResize:(NSNotification *)aNotification return; } - if (SDL_IsShapedWindow(_data->window)) { - Cocoa_ResizeWindowShape(_data->window); + if (SDL_IsShapedWindow(window)) { + Cocoa_ResizeWindowShape(window); } ScheduleContextUpdates(_data); /* The window can move during a resize event, such as when maximizing or resizing from a corner */ - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MOVED, x, y); - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESIZED, w, h); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h); - const BOOL zoomed = [_data->nswindow isZoomed]; + const BOOL zoomed = [nswindow isZoomed]; if (!zoomed) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); } else if (zoomed) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); } } @@ -429,10 +441,11 @@ - (void)windowDidEnterFullScreen:(NSNotification *)aNotification { inFullscreenTransition = NO; - if (pendingFullscreenTransition != PENDING_TRANSITION_NONE) { - pendingFullscreenTransition = PENDING_TRANSITION_NONE; + if (pendingWindowOperation == PENDING_OPERATION_LEAVE_FULLSCREEN) { + pendingWindowOperation = PENDING_OPERATION_NONE; [self setFullscreenState:NO]; } else { + pendingWindowOperation = PENDING_OPERATION_NONE; [self windowDidResize:aNotification]; } } @@ -453,10 +466,14 @@ - (void)windowDidExitFullScreen:(NSNotification *)aNotification } inFullscreenTransition = NO; - if (pendingFullscreenTransition != PENDING_TRANSITION_NONE) { - pendingFullscreenTransition = PENDING_TRANSITION_NONE; + if (pendingWindowOperation == PENDING_OPERATION_ENTER_FULLSCREEN) { + pendingWindowOperation = PENDING_OPERATION_NONE; [self setFullscreenState:YES]; + } else if (pendingWindowOperation == PENDING_OPERATION_MINIMIZE) { + pendingWindowOperation = PENDING_OPERATION_NONE; + [nswindow miniaturize:nil]; } else { + pendingWindowOperation = PENDING_OPERATION_NONE; [self windowDidResize:aNotification]; } } @@ -1095,9 +1112,14 @@ - (void)resetCursorRects Cocoa_MinimizeWindow(_THIS, SDL_Window * window) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data->nswindow; - [nswindow miniaturize:nil]; + if ([data->listener isInFullscreenTransition]) { + [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; + } else { + [nswindow miniaturize:nil]; + } [pool release]; }