diff src/video/cocoa/SDL_cocoawindow.m @ 5254:7a963be087ef

Mostly fixed fullscreen mode on Mac OS X, and you can toggle it on and off. There are still some problems with the ConvertNSRect() calculations when switching video modes, which causes wierd window positioning issues, and the fullscreen window is still minimized on exit.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 11 Feb 2011 00:25:44 -0800
parents 58265e606e4e
children 9e70b360f423
line wrap: on
line diff
--- a/src/video/cocoa/SDL_cocoawindow.m	Thu Feb 10 22:49:14 2011 -0800
+++ b/src/video/cocoa/SDL_cocoawindow.m	Fri Feb 11 00:25:44 2011 -0800
@@ -398,6 +398,22 @@
 
 @end
 
+static unsigned int
+GetStyleMask(SDL_Window * window)
+{
+    unsigned int style;
+
+    if (window->flags & SDL_WINDOW_BORDERLESS) {
+        style = NSBorderlessWindowMask;
+    } else {
+        style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
+    }
+    if (window->flags & SDL_WINDOW_RESIZABLE) {
+        style |= NSResizableWindowMask;
+    }
+    return style;
+}
+
 static int
 SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created)
 {
@@ -406,7 +422,7 @@
     SDL_WindowData *data;
 
     /* Allocate the window data */
-    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
+    data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
     if (!data) {
         SDL_OutOfMemory();
         return -1;
@@ -424,7 +440,6 @@
 
     /* Fill in the SDL window with the window data */
     {
-        SDL_Rect bounds;
         NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
         NSView *contentView = [[SDLView alloc] initWithFrame: rect
                                                     listener: data->listener];
@@ -495,16 +510,14 @@
     unsigned int style;
 
     Cocoa_GetDisplayBounds(_this, display, &bounds);
-    if ((window->flags & SDL_WINDOW_FULLSCREEN)
-        || SDL_WINDOWPOS_ISCENTERED(window->x)) {
+    if (SDL_WINDOWPOS_ISCENTERED(window->x)) {
         rect.origin.x = bounds.x + (bounds.w - window->w) / 2;
     } else if (SDL_WINDOWPOS_ISUNDEFINED(window->x)) {
         rect.origin.x = bounds.x;
     } else {
         rect.origin.x = window->x;
     }
-    if ((window->flags & SDL_WINDOW_FULLSCREEN)
-        || SDL_WINDOWPOS_ISCENTERED(window->y)) {
+    if (SDL_WINDOWPOS_ISCENTERED(window->y)) {
         rect.origin.y = bounds.y + (bounds.h - window->h) / 2;
     } else if (SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
         rect.origin.y = bounds.y;
@@ -515,14 +528,7 @@
     rect.size.height = window->h;
     ConvertNSRect(&rect);
 
-    if (window->flags & SDL_WINDOW_BORDERLESS) {
-        style = NSBorderlessWindowMask;
-    } else {
-        style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask);
-    }
-    if (window->flags & SDL_WINDOW_RESIZABLE) {
-        style |= NSResizableWindowMask;
-    }
+    style = GetStyleMask(window);
 
     /* Figure out which screen to place this window */
     NSArray *screens = [NSScreen screens];
@@ -600,14 +606,12 @@
     SDL_Rect bounds;
 
     Cocoa_GetDisplayBounds(_this, display, &bounds);
-    if ((window->flags & SDL_WINDOW_FULLSCREEN)
-        || SDL_WINDOWPOS_ISCENTERED(window->x)) {
+    if (SDL_WINDOWPOS_ISCENTERED(window->x)) {
         rect.origin.x = bounds.x + (bounds.w - window->w) / 2;
     } else {
         rect.origin.x = window->x;
     }
-    if ((window->flags & SDL_WINDOW_FULLSCREEN)
-        || SDL_WINDOWPOS_ISCENTERED(window->y)) {
+    if (SDL_WINDOWPOS_ISCENTERED(window->y)) {
         rect.origin.y = bounds.y + (bounds.h - window->h) / 2;
     } else {
         rect.origin.y = window->y;
@@ -700,6 +704,56 @@
 }
 
 void
+Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window)
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+    NSWindow *nswindow = data->nswindow;
+    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+    NSRect rect;
+    unsigned int style;
+
+    if (FULLSCREEN_VISIBLE(window)) {
+        SDL_Rect bounds;
+
+        Cocoa_GetDisplayBounds(_this, display, &bounds);
+        rect.origin.x = bounds.x;
+        rect.origin.y = bounds.y;
+        rect.size.width = bounds.w;
+        rect.size.height = bounds.h;
+        ConvertNSRect(&rect);
+
+        style = NSBorderlessWindowMask;
+    } else {
+        rect.origin.x = window->windowed.x;
+        rect.origin.y = window->windowed.y;
+        rect.size.width = window->windowed.w;
+        rect.size.height = window->windowed.h;
+        /* FIXME: This calculation is wrong, we're changing the origin */
+        ConvertNSRect(&rect);
+
+        style = GetStyleMask(window);
+    }
+
+    [nswindow setStyleMask:style];
+    [nswindow setContentSize:rect.size];
+    rect = [nswindow frameRectForContentRect:rect];
+    [nswindow setFrameOrigin:rect.origin];
+
+#ifdef FULLSCREEN_TOGGLEABLE
+    if (FULLSCREEN_VISIBLE(window)) {
+        /* OpenGL is rendering to the window, so make it visible! */
+        [nswindow setLevel:CGShieldingWindowLevel()];
+    } else {
+        [nswindow setLevel:kCGNormalWindowLevel];
+    }
+#endif
+    [nswindow makeKeyAndOrderFront:nil];
+
+    [pool release];
+}
+
+void
 Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
 {
     if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&