From 57e985189443826f0cd083471aeb0011a2976df6 Mon Sep 17 00:00:00 2001 From: crs Date: Tue, 9 Nov 2004 20:05:33 +0000 Subject: [PATCH] Fixed modifier handling on OSX client. Had hardcoded one set of modifiers for all keys for testing purposes and forgotton to fix that. Now choosing required modifiers per key. This fixes shift+arrow keys suppressing the shift key and, i think, the option key not working. --- lib/platform/COSXKeyState.cpp | 64 ++++++++++++++++++++--------------- lib/platform/COSXKeyState.h | 8 ++++- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/lib/platform/COSXKeyState.cpp b/lib/platform/COSXKeyState.cpp index 9aca430d..ed28eac1 100644 --- a/lib/platform/COSXKeyState.cpp +++ b/lib/platform/COSXKeyState.cpp @@ -264,24 +264,13 @@ COSXKeyState::mapKey(Keystrokes& keys, KeyID id, // ensure we adjust the right modifiers for remaining dead keys // and the final key. - // FIXME -- required modifier masks. we should determine this for - // each key when parsing the layout resource. for now we'll just - // force shift, option and caps-lock to always match exactly in - // addition to whatever other modifiers the key needs. -// FIXME -- this doesn't work. it forces modifiers when modifiers are -// pressed (making having two modifiers at once impossible). - static const KeyModifierMask requiredMask = - KeyModifierShift | - KeyModifierSuper | - KeyModifierCapsLock; - // add dead keys for (size_t i = 0; i < sequence.size() - 1; ++i) { // simulate press KeyButton keyButton = - addKeystrokes(keys, sequence[i].first, - sequence[i].second, - sequence[i].second | requiredMask, false); + addKeystrokes(keys, sequence[i].m_button, + sequence[i].m_requiredState, + sequence[i].m_requiredMask, false); // simulate release Keystroke keystroke; @@ -292,9 +281,9 @@ COSXKeyState::mapKey(Keystrokes& keys, KeyID id, } // add final key - return addKeystrokes(keys, sequence.back().first, - sequence.back().second, - sequence.back().second | requiredMask, + return addKeystrokes(keys, sequence.back().m_button, + sequence.back().m_requiredState, + sequence.back().m_requiredMask, isAutoRepeat); } @@ -433,7 +422,7 @@ COSXKeyState::addKeyButton(KeyButtons& keys, KeyID id) const if (keyIndex == m_keyMap.end()) { return; } - keys.push_back(keyIndex->second[0].first); + keys.push_back(keyIndex->second[0].m_button); } void @@ -473,7 +462,7 @@ COSXKeyState::handleModifierKey(void* target, KeyID id, bool down) if (keyIndex == m_keyMap.end()) { return; } - KeyButton button = keyIndex->second[0].first; + KeyButton button = keyIndex->second[0].m_button; setKeyDown(button, down); sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button); } @@ -513,13 +502,16 @@ COSXKeyState::fillSpecialKeys(CKeyIDMap& keyMap, CVirtualKeyMap& virtualKeyMap) const { // FIXME -- would like to avoid hard coded tables + CKeyEventInfo info; for (UInt32 i = 0; i < sizeof(s_controlKeys) / sizeof(s_controlKeys[0]); ++i) { const CKeyEntry& entry = s_controlKeys[i]; KeyID keyID = entry.m_keyID; - KeyButton keyButton = mapVirtualKeyToKeyButton(entry.m_virtualKey); + info.m_button = mapVirtualKeyToKeyButton(entry.m_virtualKey); + info.m_requiredMask = 0; + info.m_requiredState = 0; if (keyMap.count(keyID) == 0) { - keyMap[keyID].push_back(std::make_pair(keyButton, 0)); + keyMap[keyID].push_back(info); } if (virtualKeyMap.count(entry.m_virtualKey) == 0) { virtualKeyMap[entry.m_virtualKey] = entry.m_keyID; @@ -535,7 +527,7 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const CKCHRResource* r = m_KCHRResource; // build non-composed keys to virtual keys mapping - std::map > vkMap; + std::map vkMap; for (SInt32 i = 0; i < r->m_numTables; ++i) { // determine the modifier keys for table i KeyModifierMask mask = @@ -546,9 +538,18 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const // get character UInt8 c = r->m_characterTables[i][j]; + // save key info + // FIXME -- should set only those bits in m_requiredMask that + // correspond to modifiers that are truly necessary to + // generate the character. this mostly works as-is, though. + CKeyEventInfo info; + info.m_button = mapVirtualKeyToKeyButton(j); + info.m_requiredMask = mask; + info.m_requiredState = mask; + // save character to virtual key mapping if (keyMap.count(c) == 0) { - vkMap[c] = std::make_pair(mapVirtualKeyToKeyButton(j), mask); + vkMap[c] = info; } // skip non-glyph character @@ -565,8 +566,7 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const } // save entry for character - keyMap[keyID].push_back(std::make_pair( - mapVirtualKeyToKeyButton(j), mask)); + keyMap[keyID].push_back(info); } } @@ -602,8 +602,18 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const // to the uncomposed character. if (vkMap.count(dkr->m_completion[j][0]) != 0) { CKeySequence& sequence = keyMap[keyID]; - sequence.push_back(std::make_pair( - mapVirtualKeyToKeyButton(dkr->m_virtualKey), mask)); + + // save key info + // FIXME -- should set only those bits in m_requiredMask that + // correspond to modifiers that are truly necessary to + // generate the character. this mostly works as-is, though. + CKeyEventInfo info; + info.m_button = mapVirtualKeyToKeyButton( + dkr->m_virtualKey); + info.m_requiredMask = mask; + info.m_requiredState = mask; + + sequence.push_back(info); sequence.push_back(vkMap[dkr->m_completion[j][0]]); } } diff --git a/lib/platform/COSXKeyState.h b/lib/platform/COSXKeyState.h index 13e11642..e7972a73 100644 --- a/lib/platform/COSXKeyState.h +++ b/lib/platform/COSXKeyState.h @@ -69,7 +69,13 @@ protected: bool isAutoRepeat) const; private: - typedef std::vector > CKeySequence; + struct CKeyEventInfo { + public: + KeyButton m_button; + KeyModifierMask m_requiredMask; + KeyModifierMask m_requiredState; + }; + typedef std::vector CKeySequence; typedef std::map CKeyIDMap; typedef std::map CVirtualKeyMap;