Fixed assertion failure when minimizing a fullscreen window.

This commit is contained in:
Sam Lantinga 2013-11-11 21:21:18 -08:00
parent 75a23d99a5
commit 7cf76ffbe0
2 changed files with 51 additions and 25 deletions

View file

@ -27,6 +27,14 @@
typedef struct SDL_WindowData SDL_WindowData; 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 <NSWindowDelegate> { @interface Cocoa_WindowListener : NSResponder <NSWindowDelegate> {
SDL_WindowData *_data; SDL_WindowData *_data;
BOOL observingVisible; BOOL observingVisible;
@ -34,19 +42,15 @@ typedef struct SDL_WindowData SDL_WindowData;
BOOL wasVisible; BOOL wasVisible;
BOOL isFullscreen; BOOL isFullscreen;
BOOL inFullscreenTransition; BOOL inFullscreenTransition;
PendingWindowOperation pendingWindowOperation;
enum
{
PENDING_TRANSITION_NONE,
PENDING_TRANSITION_ENTER_FULLSCREEN,
PENDING_TRANSITION_LEAVE_FULLSCREEN
} pendingFullscreenTransition;
} }
-(void) listen:(SDL_WindowData *) data; -(void) listen:(SDL_WindowData *) data;
-(void) pauseVisibleObservation; -(void) pauseVisibleObservation;
-(void) resumeVisibleObservation; -(void) resumeVisibleObservation;
-(BOOL) setFullscreenState:(BOOL) state; -(BOOL) setFullscreenState:(BOOL) state;
-(BOOL) isInFullscreenTransition;
-(void) addPendingWindowOperation:(PendingWindowOperation) operation;
-(void) close; -(void) close;
/* Window delegate functionality */ /* Window delegate functionality */

View file

@ -103,7 +103,7 @@ GetWindowStyle(SDL_Window * window)
wasVisible = [window isVisible]; wasVisible = [window isVisible];
isFullscreen = NO; isFullscreen = NO;
inFullscreenTransition = NO; inFullscreenTransition = NO;
pendingFullscreenTransition = PENDING_TRANSITION_NONE; pendingWindowOperation = PENDING_OPERATION_NONE;
center = [NSNotificationCenter defaultCenter]; center = [NSNotificationCenter defaultCenter];
@ -199,7 +199,7 @@ GetWindowStyle(SDL_Window * window)
return NO; return NO;
} }
pendingFullscreenTransition = PENDING_TRANSITION_NONE; pendingWindowOperation = PENDING_OPERATION_NONE;
/* We can enter new style fullscreen mode for "fullscreen desktop" */ /* We can enter new style fullscreen mode for "fullscreen desktop" */
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
@ -221,9 +221,9 @@ GetWindowStyle(SDL_Window * window)
if (inFullscreenTransition) { if (inFullscreenTransition) {
if (state) { if (state) {
pendingFullscreenTransition = PENDING_TRANSITION_ENTER_FULLSCREEN; [self addPendingWindowOperation:PENDING_OPERATION_ENTER_FULLSCREEN];
} else { } else {
pendingFullscreenTransition = PENDING_TRANSITION_LEAVE_FULLSCREEN; [self addPendingWindowOperation:PENDING_OPERATION_LEAVE_FULLSCREEN];
} }
return YES; return YES;
} }
@ -232,6 +232,16 @@ GetWindowStyle(SDL_Window * window)
return YES; return YES;
} }
-(BOOL) isInFullscreenTransition
{
return inFullscreenTransition;
}
-(void) addPendingWindowOperation:(PendingWindowOperation) operation
{
pendingWindowOperation = operation;
}
- (void)close - (void)close
{ {
NSNotificationCenter *center; NSNotificationCenter *center;
@ -328,8 +338,10 @@ GetWindowStyle(SDL_Window * window)
- (void)windowDidResize:(NSNotification *)aNotification - (void)windowDidResize:(NSNotification *)aNotification
{ {
SDL_Window *window = _data->window;
NSWindow *nswindow = _data->nswindow;
int x, y, w, h; int x, y, w, h;
NSRect rect = [_data->nswindow contentRectForFrameRect:[_data->nswindow frame]]; NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
ConvertNSRect(&rect); ConvertNSRect(&rect);
x = (int)rect.origin.x; x = (int)rect.origin.x;
y = (int)rect.origin.y; y = (int)rect.origin.y;
@ -341,22 +353,22 @@ GetWindowStyle(SDL_Window * window)
return; return;
} }
if (SDL_IsShapedWindow(_data->window)) { if (SDL_IsShapedWindow(window)) {
Cocoa_ResizeWindowShape(_data->window); Cocoa_ResizeWindowShape(window);
} }
ScheduleContextUpdates(_data); ScheduleContextUpdates(_data);
/* The window can move during a resize event, such as when maximizing /* The window can move during a resize event, such as when maximizing
or resizing from a corner */ or resizing from a corner */
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MOVED, x, y); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESIZED, w, h); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
const BOOL zoomed = [_data->nswindow isZoomed]; const BOOL zoomed = [nswindow isZoomed];
if (!zoomed) { if (!zoomed) {
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
} else if (zoomed) { } else if (zoomed) {
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
} }
} }
@ -429,10 +441,11 @@ GetWindowStyle(SDL_Window * window)
{ {
inFullscreenTransition = NO; inFullscreenTransition = NO;
if (pendingFullscreenTransition != PENDING_TRANSITION_NONE) { if (pendingWindowOperation == PENDING_OPERATION_LEAVE_FULLSCREEN) {
pendingFullscreenTransition = PENDING_TRANSITION_NONE; pendingWindowOperation = PENDING_OPERATION_NONE;
[self setFullscreenState:NO]; [self setFullscreenState:NO];
} else { } else {
pendingWindowOperation = PENDING_OPERATION_NONE;
[self windowDidResize:aNotification]; [self windowDidResize:aNotification];
} }
} }
@ -453,10 +466,14 @@ GetWindowStyle(SDL_Window * window)
} }
inFullscreenTransition = NO; inFullscreenTransition = NO;
if (pendingFullscreenTransition != PENDING_TRANSITION_NONE) { if (pendingWindowOperation == PENDING_OPERATION_ENTER_FULLSCREEN) {
pendingFullscreenTransition = PENDING_TRANSITION_NONE; pendingWindowOperation = PENDING_OPERATION_NONE;
[self setFullscreenState:YES]; [self setFullscreenState:YES];
} else if (pendingWindowOperation == PENDING_OPERATION_MINIMIZE) {
pendingWindowOperation = PENDING_OPERATION_NONE;
[nswindow miniaturize:nil];
} else { } else {
pendingWindowOperation = PENDING_OPERATION_NONE;
[self windowDidResize:aNotification]; [self windowDidResize:aNotification];
} }
} }
@ -1095,9 +1112,14 @@ void
Cocoa_MinimizeWindow(_THIS, SDL_Window * window) Cocoa_MinimizeWindow(_THIS, SDL_Window * window)
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
NSWindow *nswindow = data->nswindow;
if ([data->listener isInFullscreenTransition]) {
[data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE];
} else {
[nswindow miniaturize:nil]; [nswindow miniaturize:nil];
}
[pool release]; [pool release];
} }