[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26375] trunk/blender/intern/ghost: Cocoa : correctly handle late events sent after window deactivate

Damien Plisson damien.plisson at yahoo.fr
Thu Jan 28 20:18:37 CET 2010


Revision: 26375
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26375
Author:   damien78
Date:     2010-01-28 20:18:36 +0100 (Thu, 28 Jan 2010)

Log Message:
-----------
Cocoa : correctly handle late events sent after window deactivate

Cocoa can still send events (tagged with the correct NSWindow handle) after having sent the window deactivate event.
This caused these events being discarded as there was no active window for GHOST_WindowManager.

Fix is to use this NSWindow handle to retrieve the target window and correctly push the event.

E.g. of effects of this bug: OSKey modifier stuck after having invoked Spotlight through its shortcut (Cmd + Space). This gave the impression the Blender window has not got focus back for the keyboard.

Ton, can you confirm if this fixes the "Cocoa window loses focus permanently on using Spotlight" issue you found ?

Modified Paths:
--------------
    trunk/blender/intern/ghost/GHOST_IWindow.h
    trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_Window.cpp
    trunk/blender/intern/ghost/intern/GHOST_Window.h
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h
    trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
    trunk/blender/intern/ghost/intern/GHOST_WindowManager.cpp
    trunk/blender/intern/ghost/intern/GHOST_WindowManager.h

Modified: trunk/blender/intern/ghost/GHOST_IWindow.h
===================================================================
--- trunk/blender/intern/ghost/GHOST_IWindow.h	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/GHOST_IWindow.h	2010-01-28 19:18:36 UTC (rev 26375)
@@ -73,6 +73,12 @@
 	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.
 	 */

Modified: trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_SystemCocoa.mm	2010-01-28 19:18:36 UTC (rev 26375)
@@ -1186,7 +1186,15 @@
 	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_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 @@
 	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 @@
 	
 		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) );
 			}

Modified: trunk/blender/intern/ghost/intern/GHOST_Window.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_Window.cpp	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_Window.cpp	2010-01-28 19:18:36 UTC (rev 26375)
@@ -72,6 +72,10 @@
 {
 }
 
+void* GHOST_Window::getOSWindow() const
+{
+	return NULL;
+}
 
 GHOST_TSuccess GHOST_Window::setDrawingContextType(GHOST_TDrawingContextType type)
 {

Modified: trunk/blender/intern/ghost/intern/GHOST_Window.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_Window.h	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_Window.h	2010-01-28 19:18:36 UTC (rev 26375)
@@ -124,6 +124,12 @@
 	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.
 	 */

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.h	2010-01-28 19:18:36 UTC (rev 26375)
@@ -96,6 +96,12 @@
 	 * @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.

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowCocoa.mm	2010-01-28 19:18:36 UTC (rev 26375)
@@ -465,6 +465,10 @@
 	return (m_window != 0);
 }
 
+void* GHOST_WindowCocoa::getOSWindow() const
+{
+	return (void*)m_window;
+}
 
 void GHOST_WindowCocoa::setTitle(const STR_String& title)
 {

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowManager.cpp
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowManager.cpp	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowManager.cpp	2010-01-28 19:18:36 UTC (rev 26375)
@@ -193,6 +193,18 @@
 }
 
 
+GHOST_IWindow* GHOST_WindowManager::getWindowAssociatedWithOSWindow(void* osWindow)
+{
+	std::vector<GHOST_IWindow*>::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;

Modified: trunk/blender/intern/ghost/intern/GHOST_WindowManager.h
===================================================================
--- trunk/blender/intern/ghost/intern/GHOST_WindowManager.h	2010-01-28 19:18:35 UTC (rev 26374)
+++ trunk/blender/intern/ghost/intern/GHOST_WindowManager.h	2010-01-28 19:18:36 UTC (rev 26375)
@@ -134,8 +134,15 @@
 	 * interface above for this,
 	 */
 	std::vector<GHOST_IWindow *> & 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
 	 */





More information about the Bf-blender-cvs mailing list