diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 5d1e0a67e7e..2bb446c229c 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -72,6 +72,12 @@ public: */ virtual bool getValid() const = 0; + /** + * Returns the associated OS object/handle + * @return The associated OS object/handle + */ + virtual void* getOSWindow() const = 0; + /** * Returns the type of drawing context used in this window. * @return The current type of drawing context. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 5d28e942655..23f95f95df4 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1186,7 +1186,15 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT NSEvent *event = (NSEvent *)eventPtr; GHOST_IWindow* window = m_windowManager->getActiveWindow(); - if (!window) return GHOST_kFailure; + if (!window) { + /* If no active window found, still tries to find the window associated with the event + This may happen when Cocoa continues to send some events after the window deactivate one */ + window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } + } GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData(); @@ -1238,7 +1246,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_Window* window = (GHOST_Window*)m_windowManager->getActiveWindow(); if (!window) { - return GHOST_kFailure; + /* If no active window found, still tries to find the window associated with the event + This may happen when Cocoa continues to send some events after the window deactivate one */ + window = (GHOST_Window*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } } switch ([event type]) @@ -1442,12 +1456,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) unsigned char ascii; NSString* charsIgnoringModifiers; - /* Can happen, very rarely - seems to only be when command-H makes - * the window go away and we still get an HKey up. - */ if (!window) { - //printf("\nW failure"); - return GHOST_kFailure; + /* If no active window found, still tries to find the window associated with the event + This may happen when Cocoa continues to send some events after the window deactivate one */ + window = m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]); + if (!window) { + //printf("\nW failure for event 0x%x",[event type]); + return GHOST_kFailure; + } } switch ([event type]) { @@ -1486,6 +1502,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) case NSFlagsChanged: modifiers = [event modifierFlags]; + if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) { pushEvent( new GHOST_EventKey([event timestamp]*1000, (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) ); } diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 939a911dfac..1c8b51e73a7 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -72,6 +72,10 @@ GHOST_Window::~GHOST_Window() { } +void* GHOST_Window::getOSWindow() const +{ + return NULL; +} GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type) { diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 8aab9125130..c614ae68f65 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -123,6 +123,12 @@ public: */ virtual ~GHOST_Window(); + /** + * Returns the associated OS object/handle + * @return The associated OS object/handle + */ + virtual void* getOSWindow() const; + /** * Returns the current cursor shape. * @return The current cursor shape. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index b54634b08d7..5a89b1a53a3 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -96,6 +96,12 @@ public: * @return The validity of the window. */ virtual bool getValid() const; + + /** + * Returns the associated NSWindow object + * @return The associated NSWindow object + */ + virtual void* getOSWindow() const; /** * Sets the title displayed in the title bar. diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index c02c3f11167..5dcc949ed45 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -465,6 +465,10 @@ bool GHOST_WindowCocoa::getValid() const return (m_window != 0); } +void* GHOST_WindowCocoa::getOSWindow() const +{ + return (void*)m_window; +} void GHOST_WindowCocoa::setTitle(const STR_String& title) { diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp index 15ee41e3dce..56b7c622d9a 100644 --- a/intern/ghost/intern/GHOST_WindowManager.cpp +++ b/intern/ghost/intern/GHOST_WindowManager.cpp @@ -193,6 +193,18 @@ std::vector &GHOST_WindowManager::getWindows() } +GHOST_IWindow* GHOST_WindowManager::getWindowAssociatedWithOSWindow(void* osWindow) +{ + std::vector::iterator iter; + + for (iter = m_windows.begin(); iter != m_windows.end(); iter++) { + if ((*iter)->getOSWindow() == osWindow) + return *iter; + } + + return NULL; +} + bool GHOST_WindowManager::getAnyModifiedState() { bool isAnyModified = false; diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h index 3690ad41e2c..6f48c7f4c9c 100644 --- a/intern/ghost/intern/GHOST_WindowManager.h +++ b/intern/ghost/intern/GHOST_WindowManager.h @@ -134,7 +134,14 @@ public: * interface above for this, */ std::vector & getWindows(); - + + /** + * Finds the window associated with an OS window object/handle + * @param osWindow The OS window object/handle + * @return The associated window, null if none corresponds + */ + virtual GHOST_IWindow* getWindowAssociatedWithOSWindow(void* osWindow); + /** * Return true if any windows has a modified status * @return True if any window has unsaved changes