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) +...@interface CocoaWindow: NSWindow +{ + +} +-(BOOL)canBecomeKeyWindow; + +...@end +...@implementation CocoaWindow + +-(BOOL)canBecomeKeyWindow +{ + return YES; +} + +...@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 _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs