From 37fa2d698f64e918fef84d1aa7b36f945263f8f5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 24 Oct 2013 10:10:16 +0000 Subject: [PATCH] From Stephan Huber, add support for controlling the OSXMenubarBehavior set by DisplaySettings. --- src/osgViewer/DarwinUtils.h | 19 ++++- src/osgViewer/DarwinUtils.mm | 112 +++++++++++++++++++++------ src/osgViewer/GraphicsWindowCocoa.mm | 1 + 3 files changed, 106 insertions(+), 26 deletions(-) diff --git a/src/osgViewer/DarwinUtils.h b/src/osgViewer/DarwinUtils.h index 34a3c6f0f..10b56fe71 100644 --- a/src/osgViewer/DarwinUtils.h +++ b/src/osgViewer/DarwinUtils.h @@ -21,6 +21,12 @@ //#define USE_DARWIN_COCOA_IMPLEMENTATION 1 //#define USE_DARWIN_CARBON_IMPLEMENTATION 1 +#ifdef __OBJC__ +@class MenubarToggler; +#else +class MenubarToggler; +#endif + namespace osgDarwin { @@ -43,12 +49,18 @@ class MenubarController : public osg::Referenced }; MenubarController(); + static MenubarController* instance(); void attachWindow(WindowAdapter* win); void update(); void detachWindow(osgViewer::GraphicsWindow* win); - + + void setDisplaySettings(osg::DisplaySettings* display_settings); + + protected: + ~MenubarController(); + private: typedef std::list< osg::ref_ptr< WindowAdapter > > WindowList; WindowList _list; @@ -56,6 +68,7 @@ class MenubarController : public osg::Referenced CGRect _availRect; CGRect _mainScreenBounds; OpenThreads::Mutex _mutex; + MenubarToggler* _toggler; }; @@ -89,6 +102,10 @@ struct DarwinWindowingSystemInterface : public osg::GraphicsContext::WindowingSy /** returns screen-ndx containing rect x,y,w,h */ unsigned int getScreenContaining(int x, int y, int w, int h); + virtual void setDisplaySettings(osg::DisplaySettings* display_settings) { + MenubarController::instance()->setDisplaySettings(display_settings); + } + protected: virtual void _init(); diff --git a/src/osgViewer/DarwinUtils.mm b/src/osgViewer/DarwinUtils.mm index 9a6f99c5e..08b84986d 100644 --- a/src/osgViewer/DarwinUtils.mm +++ b/src/osgViewer/DarwinUtils.mm @@ -14,32 +14,89 @@ @interface MenubarToggler : NSObject { + osg::ref_ptr _displaySettings; + osg::DisplaySettings::OSXMenubarBehavior _menubarBehavior; } --(void) show: (id) data; --(void) hide: (id) data; +-(void) show; +-(void) hide; +-(void) setDisplaySettings: (osg::DisplaySettings*) display_settings; @end @implementation MenubarToggler - - --(void) hide:(id) data +-(id) init { - OSErr error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); - if (error) { - OSG_DEBUG << "MenubarToggler::hide failed with " << error << std::endl; - } + self = [super init]; + _menubarBehavior = osg::DisplaySettings::MENUBAR_AUTO_HIDE; + _displaySettings = NULL; + return self; +} + +-(void) setDisplaySettings: (osg::DisplaySettings*) display_settings +{ + _displaySettings = display_settings; +} + +-(void) hide +{ + if(_displaySettings.valid()) _menubarBehavior = _displaySettings->getOSXMenubarBehavior(); + + if (_menubarBehavior == osg::DisplaySettings::MENUBAR_FORCE_SHOW) + return; + + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + NSApplicationPresentationOptions options; + switch(_menubarBehavior) { + case osg::DisplaySettings::MENUBAR_AUTO_HIDE: + options = NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock; + break; + + case osg::DisplaySettings::MENUBAR_FORCE_HIDE: + options = NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock; + break; + + default: + options = NSApplicationPresentationDefault; + + } + + [[NSApplication sharedApplication] setPresentationOptions: options]; + #else + SystemUIMode mode = kUIModeAllHidden; + SystemUIOptions options = 0; + switch(_menubarBehavior) { + case osg::DisplaySettings::MENUBAR_AUTO_HIDE: + options = kUIOptionAutoShowMenuBar; + break; + + case osg::DisplaySettings::MENUBAR_FORCE_HIDE: + break; + + default: + mode = kUIModeNormal; + + } + + OSErr error = SetSystemUIMode(mode, options); + if (error) { + OSG_DEBUG << "MenubarToggler::hide failed with " << error << std::endl; + } + #endif } --(void) show:(id) data +-(void) show { - OSErr error = SetSystemUIMode(kUIModeNormal, 0); - if (error) { - OSG_DEBUG << "MenubarToggler::show failed with " << error << std::endl; - } + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 + [[NSApplication sharedApplication] setPresentationOptions: NSApplicationPresentationDefault]; + #else + OSErr error = SetSystemUIMode(kUIModeNormal, 0); + if (error) { + OSG_DEBUG << "MenubarToggler::show failed with " << error << std::endl; + } + #endif } @@ -111,7 +168,7 @@ static inline CGRect toCGRect(NSRect nsRect) MenubarController::MenubarController() : osg::Referenced(), _list(), - _menubarShown(false), + _menubarShown(true), _mutex() { // the following code will query the system for the available rect on the main-display (typically the displaying showing the menubar + the dock @@ -126,12 +183,21 @@ MenubarController::MenubarController() // NSRect 0/0 is bottom/left, _mainScreenBounds 0/0 is top/left _availRect.origin.y = _mainScreenBounds.size.height - _availRect.size.height - _availRect.origin.y; - - // hide the menubar initially - SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + _toggler = [[MenubarToggler alloc] init]; + update(); +} + +MenubarController::~MenubarController() +{ + [_toggler release]; } +void MenubarController::setDisplaySettings(osg::DisplaySettings* display_settings) +{ + [_toggler setDisplaySettings:display_settings]; + update(); +} MenubarController* MenubarController::instance() @@ -207,16 +273,12 @@ void MenubarController::update() { //error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); - MenubarToggler* toggler = [[MenubarToggler alloc] init]; - [toggler performSelectorOnMainThread: @selector(hide:) withObject:NULL waitUntilDone: YES]; - [toggler autorelease]; + [_toggler performSelectorOnMainThread: @selector(hide) withObject:NULL waitUntilDone: YES]; } if (!windowsCoveringMenubarArea && !_menubarShown) { //error = SetSystemUIMode(kUIModeNormal, 0); - MenubarToggler* toggler = [[MenubarToggler alloc] init]; - [toggler performSelectorOnMainThread: @selector(show:) withObject:NULL waitUntilDone: YES]; - [toggler autorelease]; + [_toggler performSelectorOnMainThread: @selector(show) withObject:NULL waitUntilDone: YES]; } [pool release]; @@ -224,7 +286,7 @@ void MenubarController::update() OSErr error; - // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar + // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar if (windowsCoveringMenubarArea && _menubarShown) { error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index bd3c52ada..cb72652e5 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -1729,6 +1729,7 @@ struct CocoaWindowingSystemInterface : public DarwinWindowingSystemInterface return createGraphicsContextImplementation(traits); } + virtual ~CocoaWindowingSystemInterface() {