diff --git a/src/osgViewer/DarwinUtils.mm b/src/osgViewer/DarwinUtils.mm index ea1a85286..09b09944d 100755 --- a/src/osgViewer/DarwinUtils.mm +++ b/src/osgViewer/DarwinUtils.mm @@ -12,6 +12,39 @@ #include "DarwinUtils.h" #include +@interface MenubarToggler : NSObject { + +} + +-(void) show: (ID) data; +-(void) hide: (ID) data; + +@end + +@implementation MenubarToggler + + + +-(void) hide:(ID) data +{ + OSErr error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + if (error) { + osg::notify(osg::DEBUG_INFO) << "MenubarToggler::hide failed with " << error << std::endl; + } +} + + +-(void) show:(ID) data +{ + OSErr error = SetSystemUIMode(kUIModeNormal, 0); + if (error) { + osg::notify(osg::DEBUG_INFO) << "MenubarToggler::show failed with " << error << std::endl; + } +} + + +@end + namespace osgDarwin { @@ -83,9 +116,9 @@ void MenubarController::detachWindow(osgViewer::GraphicsWindow* win) // iterate through all open windows and check, if they intersect the area occupied by the menubar/dock, and if so, hide the menubar/dock + void MenubarController::update() { - OSErr error(noErr); unsigned int windowsCoveringMenubarArea = 0; unsigned int windowsIntersectingMainScreen = 0; for(WindowList::iterator i = _list.begin(); i != _list.end(); ) { @@ -115,16 +148,47 @@ void MenubarController::update() i= _list.erase(i); } - // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar + // if we use the cocoa implementation then we have a NSRunLoop in place, and so we can use the deferred menubar-toggling which is thread safe + + #ifdef USE_DARWIN_COCOA_IMPLEMENTATION + + // SetSystemUIMode is not threadsafe, you'll get crashes if you call this method from other threads + // so use a small NSObject to switch the menubar on the main thread via performSelectorOnMainThread - if (windowsCoveringMenubarArea && _menubarShown) - error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + if (windowsCoveringMenubarArea && _menubarShown) + { + + //error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + MenubarToggler* toggler = [[MenubarToggler alloc] init]; + [toggler performSelectorOnMainThread: @selector(hide:) withObject:NULL waitUntilDone: YES]; + [toggler autorelease]; + } + if (!windowsCoveringMenubarArea && !_menubarShown) + { + //error = SetSystemUIMode(kUIModeNormal, 0); + MenubarToggler* toggler = [[MenubarToggler alloc] init]; + [toggler performSelectorOnMainThread: @selector(show:) withObject:NULL waitUntilDone: YES]; + [toggler autorelease]; + } + [pool release]; - if (!windowsCoveringMenubarArea && !_menubarShown) - error = SetSystemUIMode(kUIModeNormal, 0); - _menubarShown = !windowsCoveringMenubarArea; + #else - // osg::notify(osg::DEBUG_INFO) << "MenubarController:: " << windowsCoveringMenubarArea << " windows covering the menubar/dock area, " << windowsIntersectingMainScreen << " intersecting mainscreen" << std::endl; + OSErr error; + + // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar + if (windowsCoveringMenubarArea && _menubarShown) + { + error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); + } + else + { + error = SetSystemUIMode(kUIModeNormal, 0); + } + #endif + + _menubarShown = !windowsCoveringMenubarArea; } diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index 8c92c0592..83326a3a4 100755 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -19,9 +19,9 @@ #include "DarwinUtils.h" -//#define DEBUG_OUT(s) std::cout << "GraphicsWindowCocoa :: " << s << std::endl; +#define DEBUG_OUT(s) std::cout << "GraphicsWindowCocoa :: " << s << std::endl; -#define DEBUG_OUT(s) ; +//#define DEBUG_OUT(s) ; static bool s_quit_requested = false; @@ -388,8 +388,8 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) - (void) mouseMoved:(NSEvent*)theEvent { - DEBUG_OUT("Mouse moved"); NSPoint converted_point = [self getLocalPoint: theEvent]; + DEBUG_OUT("Mouse moved" << converted_point.x << "/" << converted_point.y); _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y); } @@ -605,6 +605,8 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) { if (!_win) return; + DEBUG_OUT("middleMouseDown "); + NSPoint converted_point = [self getLocalPoint: theEvent]; if([theEvent clickCount] == 1) @@ -621,6 +623,8 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) { if (!_win) return; + DEBUG_OUT("extraMouseDown btn: " << button_number); + NSPoint converted_point = [self getLocalPoint: theEvent]; if([theEvent clickCount] == 1) { @@ -1036,18 +1040,22 @@ void GraphicsWindowCocoa::closeImplementation() MenubarController* mbc = MenubarController::instance(); if (mbc) mbc->detachWindow(this); - if (_window) { - [_window close]; - [_window release]; - } - if (_view) { [_view setGraphicsWindowCocoa: NULL]; } + + if (_window) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + // we have to close + release the window in the main-thread + + [_window performSelectorOnMainThread: @selector(close) withObject:NULL waitUntilDone: YES]; + [_window performSelectorOnMainThread: @selector(release) withObject:NULL waitUntilDone: YES]; + [pool release]; + } _window = NULL; - _view = NULL; - + _view = NULL; }