Cocoa : fix for modifiers keys handling upon application switching
authorDamien Plisson <damien.plisson@yahoo.fr>
Thu, 14 Jan 2010 16:01:05 +0000 (16:01 +0000)
committerDamien Plisson <damien.plisson@yahoo.fr>
Thu, 14 Jan 2010 16:01:05 +0000 (16:01 +0000)
- fix race condition between applicationBecomeActive, and WindowBecomeKey events that discarded the modifiers keys status change event message
- workaround for a 10.6 bug that made the Cmd (oskey) modifier erroneously on.

intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm

index 9f51d7b07487106136e5af6a40c3e6f803a1fd31..47a1acdb473b7527b10dfd299e3eecb8d215ca21 100644 (file)
@@ -264,6 +264,9 @@ protected:
        /** Event has been processed directly by Cocoa and has sent a ghost event to be dispatched */
        bool m_outsideLoopEventProcessed;
        
+       /** Raised window is not yet known by the window manager, so delay application become active event handling */
+       bool m_needDelayedApplicationBecomeActiveEventProcessing;
+       
        /** Mouse buttons state */
        GHOST_TUns32 m_pressedMouseButtons;
        
index 5f0276c3555a73cb24ad671fd0ec6a7920e75d3e..d8bb903dbe75380bc49c66b41cfb5433d3453c6a 100644 (file)
@@ -520,6 +520,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
        m_cursorDelta_x=0;
        m_cursorDelta_y=0;
        m_outsideLoopEventProcessed = false;
+       m_needDelayedApplicationBecomeActiveEventProcessing = false;
        m_displayManager = new GHOST_DisplayManagerCocoa ();
        GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
        m_displayManager->initialize();
@@ -919,6 +920,8 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
                } while (event!= nil);          
        //} while (waitForEvent && !anyProcessed); Needed only for timer implementation
        
+       if (m_needDelayedApplicationBecomeActiveEventProcessing) handleApplicationBecomeActiveEvent();
+       
        if (m_outsideLoopEventProcessed) {
                m_outsideLoopEventProcessed = false;
                return true;
@@ -934,6 +937,12 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
        //(that is when update events are sent to another application)
        unsigned int modifiers;
        GHOST_IWindow* window = m_windowManager->getActiveWindow();
+       
+       if (!window) {
+               m_needDelayedApplicationBecomeActiveEventProcessing = true;
+               return GHOST_kFailure;
+       }
+       else m_needDelayedApplicationBecomeActiveEventProcessing = false;
 
 #ifdef MAC_OS_X_VERSION_10_6
        modifiers = [NSEvent modifierFlags];
@@ -948,6 +957,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
        }
 #endif
        
+       /* Discard erroneous 10.6 modifiers values reported when switching back from spaces */
+       if ((modifiers & NSDeviceIndependentModifierFlagsMask) == 0xb00000) modifiers = 0;
+       
        if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
                pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
        }
@@ -963,6 +975,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
        
        m_modifierMask = modifiers;
        
+       m_outsideLoopEventProcessed = true;
        return GHOST_kSuccess;
 }
 
@@ -1430,7 +1443,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
         * the window go away and we still get an HKey up. 
         */
        if (!window) {
-               printf("\nW failure");
+               //printf("\nW failure");
                return GHOST_kFailure;
        }