[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23779] trunk/blender/intern/ghost/intern: Cocoa : Fullscreen mode improvement (Bugfix# 16682)
Damien Plisson
damien.plisson at yahoo.fr
Mon Oct 12 11:53:28 CEST 2009
Revision: 23779
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23779
Author: damien78
Date: 2009-10-12 11:53:28 +0200 (Mon, 12 Oct 2009)
Log Message:
-----------
Cocoa : Fullscreen mode improvement (Bugfix# 16682)
Instead of capturing the display and all user input (video game mode), the mechanism is now to hide dock & menu bar, and enlarge the window made borderless to cover the whole screen surface.
Thus all OS X window management features remains available (other windows,multi screens compatible, process switching, expose, spaces, ..)
Modified Paths:
--------------
trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm 2009-10-12 09:39:57 UTC (rev 23778)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm 2009-10-12 09:53:28 UTC (rev 23779)
@@ -733,13 +733,6 @@
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_IWindow* window = 0;
- //First check if we are in fullscreen mode
- //If so, exit it before creating a new window
- window = m_windowManager->getActiveWindow();
- if (window && (window->getState() == GHOST_kWindowStateFullScreen))
- window->setState(GHOST_kWindowStateNormal);
- window = NULL;
-
//Get the available rect for including window contents
NSRect frame = [[NSScreen mainScreen] visibleFrame];
NSRect contentRect = [NSWindow contentRectForFrameRect:frame
@@ -1008,13 +1001,6 @@
//Check open windows if some changes are not saved
if (m_windowManager->getAnyModifiedState())
{
- //First check if we are in fullscreen mode
- //If so, exit it before creating a new window
- GHOST_IWindow *window = m_windowManager->getActiveWindow();
- if (window && (window->getState() == GHOST_kWindowStateFullScreen))
- window->setState(GHOST_kWindowStateNormal);
- window = NULL;
-
int shouldQuit = NSRunAlertPanel(@"Exit Blender", @"Some changes have not been saved. Do you really want to quit ?",
@"Cancel", @"Quit anyway", nil);
if (shouldQuit == NSAlertAlternateReturn)
Modified: trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm 2009-10-12 09:39:57 UTC (rev 23778)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm 2009-10-12 09:53:28 UTC (rev 23779)
@@ -29,6 +29,11 @@
#include <Cocoa/Cocoa.h>
+#ifndef MAC_OS_X_VERSION_10_6
+//Use of the SetSystemUIMode function (64bit compatible)
+#include <Carbon/Carbon.h>
+#endif
+
#include "GHOST_WindowCocoa.h"
#include "GHOST_SystemCocoa.h"
#include "GHOST_Debug.h"
@@ -44,7 +49,7 @@
0
};
-#pragma mark Cocoa delegate object
+#pragma mark Cocoa window delegate object
@interface CocoaWindowDelegate : NSObject
{
@@ -96,6 +101,26 @@
}
@end
+#pragma mark NSWindow subclass
+//We need to subclass it to tell that even borderless (fullscreen), it can become key (receive user events)
+ at interface CocoaWindow: NSWindow
+{
+
+}
+-(BOOL)canBecomeKeyWindow;
+
+ at end
+ at implementation CocoaWindow
+
+-(BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+ at end
+
+
+
#pragma mark NSOpenGLView subclass
//We need to subclass it in order to give Cocoa the feeling key events are trapped
@interface CocoaOpenGLView : NSOpenGLView
@@ -152,7 +177,7 @@
rect.size.width = width;
rect.size.height = height;
- m_window = [[NSWindow alloc] initWithContentRect:rect
+ m_window = [[CocoaWindow alloc] initWithContentRect:rect
styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask
backing:NSBackingStoreBuffered defer:NO];
if (m_window == nil) {
@@ -212,9 +237,16 @@
if (m_window) {
[m_window close];
+ [[m_window delegate] release];
[m_window release];
m_window = nil;
}
+
+ //Check for other blender opened windows and make the frontmost key
+ NSArray *windowsList = [NSApp orderedWindows];
+ if ([windowsList count]) {
+ [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
+ }
[pool drain];
}
@@ -295,8 +327,8 @@
NSRect screenSize = [[m_window screen] visibleFrame];
//Max window contents as screen size (excluding title bar...)
- NSRect contentRect = [NSWindow contentRectForFrameRect:screenSize
- styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask)];
+ NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize
+ styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
rect = [m_window contentRectForFrameRect:[m_window frame]];
@@ -418,7 +450,11 @@
outY = screenCoord.y;
}
-
+/**
+ * @note Fullscreen switch is not actual fullscreen with display capture. As this capture removes all OS X window manager features.
+ * Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged.
+ * Thus, process switch, exposé, spaces, ... still work in fullscreen mode
+ */
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
@@ -439,9 +475,50 @@
//to give window delegate hint not to forward its deactivation to ghost wm that doesn't know view/window difference
m_fullScreen = true;
- //Only 10.6 API will enable to manage several display in fullscreen mode, and topmenu autoshow
- [m_openGLView enterFullScreenMode:[m_window screen] withOptions:nil];
+#ifdef MAC_OS_X_VERSION_10_6
+ //10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
+ //Hide menu & dock if needed
+ if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+ {
+ [NSApp setPresentationOptions:(NSApplicationPresentationHideDock | NSApplicationPresentationAutoHideMenuBar)];
+ }
+ //Make window borderless and enlarge it
+ [m_window setStyleMask:NSBorderlessWindowMask];
+ [m_window setFrame:[[m_window screen] frame] display:YES];
+#else
+ //With 10.5, we need to create a new window to change its style to borderless
+ //Hide menu & dock if needed
+ if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+ {
+ //Cocoa function in 10.5 does not allow to set the menu bar in auto-show mode [NSMenu setMenuBarVisible:NO];
+ //One of the very few 64bit compatible Carbon function
+ SetSystemUIMode(kUIModeAllHidden,kUIOptionAutoShowMenuBar);
+ }
+ //Create a fullscreen borderless window
+ CocoaWindow *tmpWindow = [[CocoaWindow alloc]
+ initWithContentRect:[[m_window screen] frame]
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:YES];
+ //Copy current window parameters
+ [tmpWindow setTitle:[m_window title]];
+ [tmpWindow setRepresentedURL:[m_window representedURL]];
+ [tmpWindow setReleasedWhenClosed:NO];
+ [tmpWindow setAcceptsMouseMovedEvents:YES];
+ [tmpWindow setDelegate:[m_window delegate]];
+ //Assign the openGL view to the new window
+ [tmpWindow setContentView:m_openGLView];
+
+ //Show the new window
+ [tmpWindow makeKeyAndOrderFront:nil];
+ //Close and release old window
+ [m_window setDelegate:nil]; // To avoid the notification of "window closed" event
+ [m_window close];
+ [m_window release];
+ m_window = tmpWindow;
+#endif
+
//Tell WM of view new size
m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
@@ -456,11 +533,48 @@
m_fullScreen = false;
//Exit fullscreen
- [m_openGLView exitFullScreenModeWithOptions:nil];
+#ifdef MAC_OS_X_VERSION_10_6
+ //Show again menu & dock if needed
+ if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+ {
+ [NSApp setPresentationOptions:NSApplicationPresentationDefault];
+ }
+ //Make window normal and resize it
+ [m_window setStyleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)];
+ [m_window setFrame:[[m_window screen] visibleFrame] display:YES];
+#else
+ //With 10.5, we need to create a new window to change its style to borderless
+ //Show menu & dock if needed
+ if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+ {
+ //Cocoa function in 10.5 does not allow to set the menu bar in auto-show mode [NSMenu setMenuBarVisible:YES];
+ SetSystemUIMode(kUIModeNormal, 0); //One of the very few 64bit compatible Carbon function
+ }
+ //Create a fullscreen borderless window
+ CocoaWindow *tmpWindow = [[CocoaWindow alloc]
+ initWithContentRect:[[m_window screen] frame]
+ styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
+ backing:NSBackingStoreBuffered
+ defer:YES];
+ //Copy current window parameters
+ [tmpWindow setTitle:[m_window title]];
+ [tmpWindow setRepresentedURL:[m_window representedURL]];
+ [tmpWindow setReleasedWhenClosed:NO];
+ [tmpWindow setAcceptsMouseMovedEvents:YES];
+ [tmpWindow setDelegate:[m_window delegate]];
- [m_window makeKeyAndOrderFront:nil];
- [m_window makeFirstResponder:m_openGLView];
+ //Assign the openGL view to the new window
+ [tmpWindow setContentView:m_openGLView];
+ //Show the new window
+ [tmpWindow makeKeyAndOrderFront:nil];
+ //Close and release old window
+ [m_window setDelegate:nil]; // To avoid the notification of "window closed" event
+ [m_window close];
+ [m_window release];
+ m_window = tmpWindow;
+#endif
+
//Tell WM of view new size
m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
@@ -534,22 +648,7 @@
if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
if (m_openGLContext != nil) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
[m_openGLContext makeCurrentContext];
-#ifdef GHOST_DRAW_CARBON_GUTTER
- // Restrict drawing to non-gutter area
- ::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
- GHOST_Rect bnds;
- getClientBounds(bnds);
- GLint b[4] =
- {
- bnds.m_l,
- bnds.m_t+s_sizeRectSize,
- bnds.m_r-bnds.m_l,
- bnds.m_b-bnds.m_t
- };
- GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
-#endif //GHOST_DRAW_CARBON_GUTTER
[pool drain];
return GHOST_kSuccess;
}
@@ -725,7 +824,6 @@
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
{
- printf("\ncursor grab %i",grab);
if (grab)
{
//No need to perform grab without warp as it is always on in OS X
More information about the Bf-blender-cvs
mailing list