From b9b95be37438198fc484e37fc240114111216175 Mon Sep 17 00:00:00 2001 From: Nathan Letwory Date: Mon, 15 Nov 2010 12:05:11 +0000 Subject: Fix [#24310] With high poly numbers when sculpting, modifier keys hang 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 | 83 +++++++++++++++++++++++++++++++ intern/ghost/intern/GHOST_SystemWin32.h | 17 +++++++ 2 files changed, 100 insertions(+) (limited to 'intern') 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. -- cgit v1.2.3