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.
This commit is contained in:
crs 2004-11-09 20:05:33 +00:00
parent fb266a00fd
commit 57e9851894
2 changed files with 44 additions and 28 deletions

View File

@ -264,24 +264,13 @@ COSXKeyState::mapKey(Keystrokes& keys, KeyID id,
// ensure we adjust the right modifiers for remaining dead keys // ensure we adjust the right modifiers for remaining dead keys
// and the final key. // 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 // add dead keys
for (size_t i = 0; i < sequence.size() - 1; ++i) { for (size_t i = 0; i < sequence.size() - 1; ++i) {
// simulate press // simulate press
KeyButton keyButton = KeyButton keyButton =
addKeystrokes(keys, sequence[i].first, addKeystrokes(keys, sequence[i].m_button,
sequence[i].second, sequence[i].m_requiredState,
sequence[i].second | requiredMask, false); sequence[i].m_requiredMask, false);
// simulate release // simulate release
Keystroke keystroke; Keystroke keystroke;
@ -292,9 +281,9 @@ COSXKeyState::mapKey(Keystrokes& keys, KeyID id,
} }
// add final key // add final key
return addKeystrokes(keys, sequence.back().first, return addKeystrokes(keys, sequence.back().m_button,
sequence.back().second, sequence.back().m_requiredState,
sequence.back().second | requiredMask, sequence.back().m_requiredMask,
isAutoRepeat); isAutoRepeat);
} }
@ -433,7 +422,7 @@ COSXKeyState::addKeyButton(KeyButtons& keys, KeyID id) const
if (keyIndex == m_keyMap.end()) { if (keyIndex == m_keyMap.end()) {
return; return;
} }
keys.push_back(keyIndex->second[0].first); keys.push_back(keyIndex->second[0].m_button);
} }
void void
@ -473,7 +462,7 @@ COSXKeyState::handleModifierKey(void* target, KeyID id, bool down)
if (keyIndex == m_keyMap.end()) { if (keyIndex == m_keyMap.end()) {
return; return;
} }
KeyButton button = keyIndex->second[0].first; KeyButton button = keyIndex->second[0].m_button;
setKeyDown(button, down); setKeyDown(button, down);
sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button); sendKeyEvent(target, down, false, id, getActiveModifiers(), 0, button);
} }
@ -513,13 +502,16 @@ COSXKeyState::fillSpecialKeys(CKeyIDMap& keyMap,
CVirtualKeyMap& virtualKeyMap) const CVirtualKeyMap& virtualKeyMap) const
{ {
// FIXME -- would like to avoid hard coded tables // FIXME -- would like to avoid hard coded tables
CKeyEventInfo info;
for (UInt32 i = 0; i < sizeof(s_controlKeys) / for (UInt32 i = 0; i < sizeof(s_controlKeys) /
sizeof(s_controlKeys[0]); ++i) { sizeof(s_controlKeys[0]); ++i) {
const CKeyEntry& entry = s_controlKeys[i]; const CKeyEntry& entry = s_controlKeys[i];
KeyID keyID = entry.m_keyID; 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) { 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) { if (virtualKeyMap.count(entry.m_virtualKey) == 0) {
virtualKeyMap[entry.m_virtualKey] = entry.m_keyID; virtualKeyMap[entry.m_virtualKey] = entry.m_keyID;
@ -535,7 +527,7 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const
CKCHRResource* r = m_KCHRResource; CKCHRResource* r = m_KCHRResource;
// build non-composed keys to virtual keys mapping // build non-composed keys to virtual keys mapping
std::map<UInt8, std::pair<KeyButton, KeyModifierMask> > vkMap; std::map<UInt8, CKeyEventInfo> vkMap;
for (SInt32 i = 0; i < r->m_numTables; ++i) { for (SInt32 i = 0; i < r->m_numTables; ++i) {
// determine the modifier keys for table i // determine the modifier keys for table i
KeyModifierMask mask = KeyModifierMask mask =
@ -546,9 +538,18 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const
// get character // get character
UInt8 c = r->m_characterTables[i][j]; 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 // save character to virtual key mapping
if (keyMap.count(c) == 0) { if (keyMap.count(c) == 0) {
vkMap[c] = std::make_pair(mapVirtualKeyToKeyButton(j), mask); vkMap[c] = info;
} }
// skip non-glyph character // skip non-glyph character
@ -565,8 +566,7 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const
} }
// save entry for character // save entry for character
keyMap[keyID].push_back(std::make_pair( keyMap[keyID].push_back(info);
mapVirtualKeyToKeyButton(j), mask));
} }
} }
@ -602,8 +602,18 @@ COSXKeyState::fillKCHRKeysMap(CKeyIDMap& keyMap) const
// to the uncomposed character. // to the uncomposed character.
if (vkMap.count(dkr->m_completion[j][0]) != 0) { if (vkMap.count(dkr->m_completion[j][0]) != 0) {
CKeySequence& sequence = keyMap[keyID]; 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]]); sequence.push_back(vkMap[dkr->m_completion[j][0]]);
} }
} }

View File

@ -69,7 +69,13 @@ protected:
bool isAutoRepeat) const; bool isAutoRepeat) const;
private: private:
typedef std::vector<std::pair<KeyButton, KeyModifierMask> > CKeySequence; struct CKeyEventInfo {
public:
KeyButton m_button;
KeyModifierMask m_requiredMask;
KeyModifierMask m_requiredState;
};
typedef std::vector<CKeyEventInfo> CKeySequence;
typedef std::map<KeyID, CKeySequence> CKeyIDMap; typedef std::map<KeyID, CKeySequence> CKeyIDMap;
typedef std::map<UInt32, KeyID> CVirtualKeyMap; typedef std::map<UInt32, KeyID> CVirtualKeyMap;