Fix [#24310] With high poly numbers when sculpting, modifier keys hang
authorNathan Letwory <nathan@letworyinteractive.com>
Mon, 15 Nov 2010 12:05:11 +0000 (12:05 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Mon, 15 Nov 2010 12:05:11 +0000 (12:05 +0000)
reported by Eclectiel L

When working with very heavy scenes Blender can seem to 'hang' (not responding). Key events that happen
during this period may get lost, especially for modifier keys.

Adding extra handling to account for these situations.

intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_SystemWin32.h

index 42bb240389570e0e331aa76c5c242d41cf2a24f2..09b53544e31f3246505432e03bd99ce44d9bf9e3 100644 (file)
@@ -399,6 +399,84 @@ GHOST_TSuccess GHOST_SystemWin32::exit()
        return GHOST_System::exit();
 }
 
+void GHOST_SystemWin32::triggerKey(GHOST_IWindow *window, bool down, GHOST_TKey key)
+{
+       GHOST_Event *extra = new GHOST_EventKey(getSystem()->getMilliSeconds(), down ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, '\0');
+       ((GHOST_SystemWin32*)getSystem())->pushEvent(extra);
+}
+void GHOST_SystemWin32::handleModifierKeys(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, GHOST_ModifierKeys &oldModifiers, GHOST_ModifierKeys &newModifiers) const
+{
+       switch(wParam) {
+               case VK_SHIFT:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftAlt), GHOST_kKeyLeftAlt);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightAlt) != newModifiers.get(GHOST_kModifierKeyRightAlt);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightAlt), GHOST_kKeyRightAlt);
+                                       }
+                               }
+                               lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftControl), GHOST_kKeyLeftControl);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightControl) != newModifiers.get(GHOST_kModifierKeyRightControl);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightControl), GHOST_kKeyRightControl);
+                                       }
+                               }
+                       }
+                       break;
+               case VK_CONTROL:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftAlt) != newModifiers.get(GHOST_kModifierKeyLeftAlt);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftAlt), GHOST_kKeyLeftAlt);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightAlt) != newModifiers.get(GHOST_kModifierKeyRightAlt);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightAlt), GHOST_kKeyRightAlt);
+                                       }
+                               }
+                               lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftShift), GHOST_kKeyLeftShift);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightShift) != newModifiers.get(GHOST_kModifierKeyRightShift);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightShift), GHOST_kKeyRightShift);
+                                       }
+                               }
+                       }
+                       break;
+               case VK_MENU:
+                       {
+                               bool lchanged = oldModifiers.get(GHOST_kModifierKeyLeftShift) != newModifiers.get(GHOST_kModifierKeyLeftShift);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftShift), GHOST_kKeyLeftShift);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightShift) != newModifiers.get(GHOST_kModifierKeyRightShift);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightShift), GHOST_kKeyRightShift);
+                                       }
+                               }
+                               lchanged = oldModifiers.get(GHOST_kModifierKeyLeftControl) != newModifiers.get(GHOST_kModifierKeyLeftControl);
+                               if(lchanged) {
+                                       ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyLeftControl), GHOST_kKeyLeftControl);
+                               } else {
+                                       bool rchanged = oldModifiers.get(GHOST_kModifierKeyRightControl) != newModifiers.get(GHOST_kModifierKeyRightControl);
+                                       if (rchanged) {
+                                               ((GHOST_SystemWin32*)getSystem())->triggerKey(window, newModifiers.get(GHOST_kModifierKeyRightControl), GHOST_kKeyRightControl);
+                                       }
+                               }
+                       }
+                       break;
+               default:
+                       break;
+       }
+}
 
 GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const
 {
@@ -409,6 +487,11 @@ GHOST_TKey GHOST_SystemWin32::convertKey(GHOST_IWindow *window, WPARAM wParam, L
        GHOST_ModifierKeys oldModifiers, newModifiers;
        system->retrieveModifierKeys(oldModifiers);
        system->getModifierKeys(newModifiers);
+
+       // check if modifier keys different from this event have changed and trigger those
+       // This can happen when some action takes a long time (Blender not responding), resulting
+       // in dropped events.
+       system->handleModifierKeys(window, wParam, lParam, oldModifiers, newModifiers);
        
        //std::cout << wParam << " " << system->m_curKeyStatus[wParam] << " shift pressed: " << system->shiftPressed() << std::endl;
 
index 88705fe2ce441d3f7a8af826740d032ffecfbc0e..bda0c9fb9be7f89131cefefae1800a9de31d3c50 100644 (file)
@@ -235,12 +235,29 @@ protected:
        
        /**
         * Converts raw WIN32 key codes from the wndproc to GHOST keys.
+        * @param window->      The window for this handling
         * @param wParam        The wParam from the wndproc
         * @param lParam        The lParam from the wndproc
         * @return The GHOST key (GHOST_kKeyUnknown if no match).
         */
        virtual GHOST_TKey convertKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam) const;
 
+       /**
+        * @param window        The window for this handling
+        * @param wParam        The wParam from the wndproc
+        * @param lParam        The lParam from the wndproc
+        * @param oldModifiers  The old modifiers
+        * @param newModifiers  The new modifiers
+        */
+       virtual void handleModifierKeys(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, GHOST_ModifierKeys &oldModifiers, GHOST_ModifierKeys &newModifiers) const;
+       /**
+        * Immediately push key event for given key
+        * @param window        The window for this handling
+        * @param down          Whether we send up or down event
+        * @param key           The key to send the event for
+        */
+       virtual void triggerKey(GHOST_IWindow *window, bool down, GHOST_TKey key);
+
        /**
         * Creates modifier key event(s) and updates the key data stored locally (m_modifierKeys).
         * With the modifier keys, we want to distinguish left and right keys.