Fixed handling of some keystrokes on win32. Pressing a dead key
and then space should convert the dead key to a non-dead key but previous the key was discarded. Fixed that but VkKeyScan() fails in this case so added special case to fix that (assuming AltGr is required). VkKeyScan() can return the wrong result for characters that have more than one virtual key mapped to them. AltGr+9 (^) on the French layout has this problem. Now detecting that problem and using the current keyboard state to decide if AltGr is required.
This commit is contained in:
parent
be07a171cc
commit
5488b77d61
|
@ -1144,7 +1144,7 @@ static const KeyID g_virtualKey[][2] =
|
||||||
/* 0x1d */ kKeyNone, kKeyNone, // VK_NONCONVERT
|
/* 0x1d */ kKeyNone, kKeyNone, // VK_NONCONVERT
|
||||||
/* 0x1e */ kKeyNone, kKeyNone, // VK_ACCEPT
|
/* 0x1e */ kKeyNone, kKeyNone, // VK_ACCEPT
|
||||||
/* 0x1f */ kKeyNone, kKeyNone, // VK_MODECHANGE
|
/* 0x1f */ kKeyNone, kKeyNone, // VK_MODECHANGE
|
||||||
/* 0x20 */ 0x0020, kKeyNone, // VK_SPACE
|
/* 0x20 */ kKeyNone, kKeyNone, // VK_SPACE
|
||||||
/* 0x21 */ kKeyKP_PageUp, kKeyPageUp, // VK_PRIOR
|
/* 0x21 */ kKeyKP_PageUp, kKeyPageUp, // VK_PRIOR
|
||||||
/* 0x22 */ kKeyKP_PageDown, kKeyPageDown, // VK_NEXT
|
/* 0x22 */ kKeyKP_PageDown, kKeyPageDown, // VK_NEXT
|
||||||
/* 0x23 */ kKeyKP_End, kKeyEnd, // VK_END
|
/* 0x23 */ kKeyKP_End, kKeyEnd, // VK_END
|
||||||
|
@ -1421,7 +1421,8 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
|
|
||||||
// convert to ascii
|
// convert to ascii
|
||||||
WORD ascii;
|
WORD ascii;
|
||||||
int result = ToAscii(vkCode, scanCode, m_keys, &ascii, 0);
|
int result = ToAscii(vkCode, scanCode, m_keys, &ascii,
|
||||||
|
((menu & 0x80) == 0) ? 0 : 1);
|
||||||
|
|
||||||
// restore control state
|
// restore control state
|
||||||
m_keys[VK_LCONTROL] = lControl;
|
m_keys[VK_LCONTROL] = lControl;
|
||||||
|
@ -1504,13 +1505,38 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
// set mask
|
// set mask
|
||||||
*altgr = false;
|
*altgr = false;
|
||||||
if (id != kKeyNone && id != kKeyMultiKey && c != 0) {
|
if (id != kKeyNone && id != kKeyMultiKey && c != 0) {
|
||||||
// note if key requires AltGr
|
// note if key requires AltGr. VkKeyScan() can have a problem
|
||||||
SHORT virtualKeyAndModifierState = VkKeyScan(c);
|
// with some characters. there are two problems in particular.
|
||||||
BYTE modifierState = HIBYTE(virtualKeyAndModifierState);
|
// first, typing a dead key then pressing space will cause
|
||||||
if ((modifierState & 6) == 6) {
|
// VkKeyScan() to return 0xffff. second, certain characters
|
||||||
// key requires ctrl and alt == AltGr
|
// may map to multiple virtual keys and we might get the wrong
|
||||||
|
// one. if that happens then we might not get the right
|
||||||
|
// modifier mask. AltGr+9 on the french keyboard layout (^)
|
||||||
|
// has this problem. in the first case, we'll assume AltGr is
|
||||||
|
// required (only because it solves the problems we've seen
|
||||||
|
// so far). in the second, we'll use whatever the keyboard
|
||||||
|
// state says.
|
||||||
|
WORD virtualKeyAndModifierState = VkKeyScan(c);
|
||||||
|
if (virtualKeyAndModifierState == 0xffff) {
|
||||||
|
// there is no mapping. assume AltGr.
|
||||||
|
LOG((CLOG_DEBUG1 "no VkKeyScan() mapping"));
|
||||||
*altgr = true;
|
*altgr = true;
|
||||||
}
|
}
|
||||||
|
else if (LOBYTE(virtualKeyAndModifierState) != vkCode) {
|
||||||
|
// we didn't get the key that was actually pressed
|
||||||
|
LOG((CLOG_DEBUG1 "VkKeyScan() mismatch"));
|
||||||
|
if ((m_keys[VK_CONTROL] & 0x80) != 0 &&
|
||||||
|
(m_keys[VK_MENU] & 0x80) != 0) {
|
||||||
|
*altgr = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BYTE modifierState = HIBYTE(virtualKeyAndModifierState);
|
||||||
|
if ((modifierState & 6) == 6) {
|
||||||
|
// key requires ctrl and alt == AltGr
|
||||||
|
*altgr = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// map modifier key
|
// map modifier key
|
||||||
KeyModifierMask mask = 0;
|
KeyModifierMask mask = 0;
|
||||||
|
|
Loading…
Reference in New Issue