Fixed fullscreen modes with Cocoa video driver.
authorSam Lantinga <slouken@libsdl.org>
Sun, 06 Aug 2006 08:55:37 +0000
changeset 1973 81255f93dfcd
parent 1972 a0e278364188
child 1974 70deaf574153
Fixed fullscreen modes with Cocoa video driver.
src/video/cocoa/SDL_cocoamodes.m
src/video/cocoa/SDL_cocoaopengl.m
src/video/cocoa/SDL_cocoawindow.m
--- a/src/video/cocoa/SDL_cocoamodes.m	Sun Aug 06 07:29:38 2006 +0000
+++ b/src/video/cocoa/SDL_cocoamodes.m	Sun Aug 06 08:55:37 2006 +0000
@@ -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;
 }
 
--- a/src/video/cocoa/SDL_cocoaopengl.m	Sun Aug 06 07:29:38 2006 +0000
+++ b/src/video/cocoa/SDL_cocoaopengl.m	Sun Aug 06 08:55:37 2006 +0000
@@ -247,11 +247,6 @@
 
     /* 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 @@
         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];
--- a/src/video/cocoa/SDL_cocoawindow.m	Sun Aug 06 07:29:38 2006 +0000
+++ b/src/video/cocoa/SDL_cocoawindow.m	Sun Aug 06 08:55:37 2006 +0000
@@ -262,6 +262,24 @@
 
 @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 @@
         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];