From 905c987428e224947f66b30e94094069386e21a7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 6 Aug 2006 08:55:37 +0000 Subject: [PATCH] Fixed fullscreen modes with Cocoa video driver. --- src/video/cocoa/SDL_cocoamodes.m | 34 +++++++++++++++++++++++++++++++ src/video/cocoa/SDL_cocoaopengl.m | 13 ++++++------ src/video/cocoa/SDL_cocoawindow.m | 20 +++++++++++++++++- 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index 330b19146..51ecf05bb 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -23,6 +23,24 @@ #include "SDL_cocoavideo.h" +/* + Add methods to get at private members of NSScreen. + Since there is a bug in Apple's screen switching code + that does not update this variable when switching + to fullscreen, we'll set it manually (but only for the + main screen). +*/ +@interface NSScreen (NSScreenAccess) +- (void) setFrame:(NSRect)frame; +@end + +@implementation NSScreen (NSScreenAccess) +- (void) setFrame:(NSRect)frame; +{ + _frame = frame; +} +@end + static void CG_SetError(const char *prefix, CGDisplayErr result) { @@ -164,6 +182,7 @@ display.driverdata = displaydata; SDL_AddVideoDisplay(&display); } + SDL_stack_free(displays); } static void @@ -220,11 +239,24 @@ goto ERR_NO_SWITCH; } + /* Hide the menu bar so it doesn't intercept events */ + HideMenuBar(); + /* Fade in again (asynchronously) */ if (fade_token != kCGDisplayFadeReservationInvalidToken) { CGDisplayFade(fade_token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE); CGReleaseDisplayFadeReservation(fade_token); } + + /* + There is a bug in Cocoa where NSScreen doesn't synchronize + with CGDirectDisplay, so the main screen's frame is wrong. + As a result, coordinate translation produces incorrect results. + We can hack around this bug by setting the screen rect + ourselves. This hack should be removed if/when the bug is fixed. + */ + [[NSScreen mainScreen] setFrame:NSMakeRect(0,0,mode->w,mode->h)]; + return 0; /* Since the blanking window covers *all* windows (even force quit) correct recovery is crucial */ @@ -253,6 +285,8 @@ } } CGReleaseAllDisplays(); + ShowMenuBar(); + _this->current_display = saved_display; } diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index 8a8ac3b90..bbcf6ffa7 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -247,11 +247,6 @@ - (CGLContextObj)CGLContextObj; /* End Wisdom from Apple Engineer section. --ryan. */ - /* FIXME: should this go somewhere else? */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - [nscontext setFullScreen]; - } - [pool release]; return nscontext; } @@ -267,8 +262,12 @@ - (CGLContextObj)CGLContextObj; SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata; NSOpenGLContext *nscontext = (NSOpenGLContext *)context; - [nscontext setView:[windowdata->window contentView]]; - [nscontext update]; + if (window->flags & SDL_WINDOW_FULLSCREEN) { + [nscontext setFullScreen]; + } else { + [nscontext setView:[windowdata->window contentView]]; + [nscontext update]; + } [nscontext makeCurrentContext]; } else { [NSOpenGLContext clearCurrentContext]; diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 6f2a0e4b9..a522e86f6 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -262,6 +262,24 @@ - (void)scrollWheel:(NSEvent *)theEvent @end +@interface SDLWindow : NSWindow +/* These are needed for borderless/fullscreen windows */ +- (BOOL)canBecomeKeyWindow; +- (BOOL)canBecomeMainWindow; +@end + +@implementation SDLWindow +- (BOOL)canBecomeKeyWindow +{ + return YES; +} + +- (BOOL)canBecomeMainWindow +{ + return YES; +} +@end + static int SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created) { @@ -379,7 +397,7 @@ - (void)scrollWheel:(NSEvent *)theEvent style |= NSResizableWindowMask; } - nswindow = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE]; + nswindow = [[SDLWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE]; [pool release];