diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 42bb2403895..09b53544e31 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -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; diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index 88705fe2ce4..bda0c9fb9be 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -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.