Changeset 10340

Show
Ignore:
Timestamp:
06/12/09 12:00:08 (6 years ago)
Author:
robert
Message:

From Stephan Huber, "here are some small fixes/enahncements for the cocoa backend to allow
proper functioning when running the osgViewer run-loop in a secondary
thread (e.g. when embedding GraphicsWindowCocoa?-windows in a full blown
cocoa application).

OS X is picky when you want to change the user-interface from another
thread than the main thread, not all UI stuff is thread-safe. So now
window closes and showing / hiding the menu bar is done in the main
thread via Cocoa's performSelectorOnMainThread-mechanism.

These changes don't affect the normal osgViewer usage pattern."

Location:
OpenSceneGraph/trunk/src/osgViewer
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgViewer/DarwinUtils.mm

    r10208 r10340  
    1313#include <Cocoa/Cocoa.h> 
    1414 
     15@interface MenubarToggler : NSObject { 
     16 
     17} 
     18 
     19-(void) show: (ID) data; 
     20-(void) hide: (ID) data; 
     21 
     22@end 
     23 
     24@implementation MenubarToggler 
     25 
     26 
     27 
     28-(void) hide:(ID) data  
     29{ 
     30    OSErr error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
     31    if (error) { 
     32        osg::notify(osg::DEBUG_INFO) << "MenubarToggler::hide failed with " << error << std::endl; 
     33    } 
     34} 
     35 
     36 
     37-(void) show:(ID) data  
     38{ 
     39    OSErr error = SetSystemUIMode(kUIModeNormal, 0); 
     40    if (error) { 
     41        osg::notify(osg::DEBUG_INFO) << "MenubarToggler::show failed with " << error << std::endl; 
     42    } 
     43} 
     44 
     45 
     46@end 
     47 
    1548namespace osgDarwin { 
    1649 
     
    84117// iterate through all open windows and check, if they intersect the area occupied by the menubar/dock, and if so, hide the menubar/dock 
    85118 
     119 
    86120void MenubarController::update()  
    87121{ 
    88     OSErr error(noErr); 
    89122    unsigned int windowsCoveringMenubarArea = 0;     
    90123    unsigned int windowsIntersectingMainScreen = 0; 
     
    116149    } 
    117150     
    118     // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar 
    119          
    120     if (windowsCoveringMenubarArea && _menubarShown) 
    121         error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
    122      
    123     if (!windowsCoveringMenubarArea && !_menubarShown) 
    124         error = SetSystemUIMode(kUIModeNormal, 0); 
    125         _menubarShown = !windowsCoveringMenubarArea; 
    126      
    127     // osg::notify(osg::DEBUG_INFO) << "MenubarController:: " << windowsCoveringMenubarArea << " windows covering the menubar/dock area, " << windowsIntersectingMainScreen << " intersecting mainscreen" << std::endl; 
     151    // 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 
     152             
     153    #ifdef USE_DARWIN_COCOA_IMPLEMENTATION 
     154     
     155        // SetSystemUIMode is not threadsafe, you'll get crashes if you call this method from other threads 
     156        // so use a small NSObject to switch the menubar on the main thread via performSelectorOnMainThread 
     157         
     158        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
     159        if (windowsCoveringMenubarArea && _menubarShown)  
     160        { 
     161             
     162            //error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
     163            MenubarToggler* toggler = [[MenubarToggler alloc] init]; 
     164            [toggler performSelectorOnMainThread: @selector(hide:) withObject:NULL waitUntilDone: YES]; 
     165            [toggler autorelease]; 
     166        } 
     167        if (!windowsCoveringMenubarArea && !_menubarShown)  
     168        { 
     169            //error = SetSystemUIMode(kUIModeNormal, 0); 
     170            MenubarToggler* toggler = [[MenubarToggler alloc] init]; 
     171            [toggler performSelectorOnMainThread: @selector(show:) withObject:NULL waitUntilDone: YES]; 
     172            [toggler autorelease]; 
     173        } 
     174        [pool release]; 
     175     
     176    #else 
     177     
     178        OSErr error; 
     179         
     180          // see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar 
     181        if (windowsCoveringMenubarArea && _menubarShown)  
     182        { 
     183            error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); 
     184        }  
     185        else  
     186        { 
     187            error = SetSystemUIMode(kUIModeNormal, 0); 
     188        } 
     189    #endif 
     190     
     191    _menubarShown = !windowsCoveringMenubarArea; 
    128192} 
    129193 
  • OpenSceneGraph/trunk/src/osgViewer/GraphicsWindowCocoa.mm

    r10285 r10340  
    2020#include "DarwinUtils.h" 
    2121 
    22 //#define DEBUG_OUT(s) std::cout << "GraphicsWindowCocoa :: " << s << std::endl; 
    23  
    24 #define DEBUG_OUT(s) ; 
     22#define DEBUG_OUT(s) std::cout << "GraphicsWindowCocoa :: " << s << std::endl; 
     23 
     24//#define DEBUG_OUT(s) ; 
    2525 
    2626static bool s_quit_requested = false; 
     
    389389- (void) mouseMoved:(NSEvent*)theEvent  
    390390{ 
    391     DEBUG_OUT("Mouse moved"); 
    392391    NSPoint converted_point = [self getLocalPoint: theEvent]; 
     392    DEBUG_OUT("Mouse moved" << converted_point.x << "/" << converted_point.y); 
    393393    _win->getEventQueue()->mouseMotion(converted_point.x, converted_point.y); 
    394394} 
     
    606606    if (!_win) return; 
    607607     
     608    DEBUG_OUT("middleMouseDown "); 
     609     
    608610    NSPoint converted_point = [self getLocalPoint: theEvent]; 
    609611     
     
    621623{ 
    622624    if (!_win) return; 
     625     
     626    DEBUG_OUT("extraMouseDown btn: " << button_number); 
    623627     
    624628    NSPoint converted_point = [self getLocalPoint: theEvent]; 
     
    10371041    if (mbc) mbc->detachWindow(this); 
    10381042     
    1039     if (_window) { 
    1040         [_window close]; 
    1041         [_window release]; 
    1042     } 
    1043      
    10441043    if (_view) { 
    10451044        [_view setGraphicsWindowCocoa: NULL]; 
    10461045    } 
     1046         
     1047    if (_window) { 
     1048        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     1049         
     1050        // we have to close + release the window in the main-thread 
     1051         
     1052        [_window performSelectorOnMainThread: @selector(close) withObject:NULL waitUntilDone: YES]; 
     1053        [_window performSelectorOnMainThread: @selector(release) withObject:NULL waitUntilDone: YES]; 
     1054        [pool release]; 
     1055    } 
    10471056     
    10481057    _window = NULL; 
    1049     _view = NULL; 
    1050      
     1058    _view = NULL;     
    10511059} 
    10521060