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:
parent
fb266a00fd
commit
57e9851894
|
@ -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]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue