Fix [#24310] With high poly numbers when sculpting, modifier keys hang
[blender-staging.git] / intern / ghost / intern / GHOST_SystemWin32.cpp
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;