Fixed handling of a dead key followed by space on win32 and X11.
A dead key followed by space should convert the dead key to a regular character.
This commit is contained in:
parent
99792b13a5
commit
e1985f52c9
|
@ -127,8 +127,8 @@ CMSWindowsSecondaryScreen::keyDown(KeyID key,
|
||||||
// generate key events
|
// generate key events
|
||||||
doKeystrokes(keys, 1);
|
doKeystrokes(keys, 1);
|
||||||
|
|
||||||
// do not record button down if button is 0 (invalid)
|
// do not record button down if button or virtual key is 0 (invalid)
|
||||||
if (button != 0) {
|
if (button != 0 && virtualKey != 0) {
|
||||||
// note that key is now down
|
// note that key is now down
|
||||||
m_serverKeyMap[button] = virtualKey;
|
m_serverKeyMap[button] = virtualKey;
|
||||||
m_keys[virtualKey] |= 0x80;
|
m_keys[virtualKey] |= 0x80;
|
||||||
|
@ -956,21 +956,48 @@ CMSWindowsSecondaryScreen::mapKey(Keystrokes& keys, UINT& virtualKey,
|
||||||
virtualKey = mapCharacter(keys, multiByte[0], hkl, m_mask, mask, action);
|
virtualKey = mapCharacter(keys, multiByte[0], hkl, m_mask, mask, action);
|
||||||
if (virtualKey != static_cast<UINT>(-1)) {
|
if (virtualKey != static_cast<UINT>(-1)) {
|
||||||
LOG((CLOG_DEBUG2 "KeyID 0x%08x maps to character %u", id, (unsigned char)multiByte[0]));
|
LOG((CLOG_DEBUG2 "KeyID 0x%08x maps to character %u", id, (unsigned char)multiByte[0]));
|
||||||
|
if ((MapVirtualKey(virtualKey, 2) & 0x80000000u) != 0) {
|
||||||
|
// it looks like this character is a dead key but
|
||||||
|
// MapVirtualKey() will claim it's a dead key even if it's
|
||||||
|
// not (though i don't think it ever claims it's not when
|
||||||
|
// it is). we need a backup test to ensure that this is
|
||||||
|
// really a dead key. we could use ToAscii() for this but
|
||||||
|
// that keeps state and it's a hassle to restore that state.
|
||||||
|
// OemKeyScan() appears to do the trick. if the character
|
||||||
|
// cannot be generated with a single keystroke then it
|
||||||
|
// returns 0xffffffff.
|
||||||
|
if (OemKeyScan(multiByte[0]) != 0xffffffffu) {
|
||||||
|
// character mapped to a dead key but we want the
|
||||||
|
// character for real so send a space key afterwards.
|
||||||
|
LOG((CLOG_DEBUG2 "character mapped to dead key"));
|
||||||
|
Keystroke keystroke;
|
||||||
|
keystroke.m_virtualKey = VK_SPACE;
|
||||||
|
keystroke.m_press = true;
|
||||||
|
keystroke.m_repeat = false;
|
||||||
|
keys.push_back(keystroke);
|
||||||
|
keystroke.m_press = false;
|
||||||
|
keys.push_back(keystroke);
|
||||||
|
|
||||||
|
// ignore the release of this key since we already
|
||||||
|
// handled it in mapCharacter().
|
||||||
|
virtualKey = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return m_mask;
|
return m_mask;
|
||||||
}
|
}
|
||||||
nChars = MultiByteToWideChar(codePage,
|
nChars = MultiByteToWideChar(codePage,
|
||||||
MB_COMPOSITE | MB_ERR_INVALID_CHARS,
|
MB_COMPOSITE | MB_ERR_INVALID_CHARS,
|
||||||
multiByte, nChars,
|
multiByte, nChars,
|
||||||
unicode, 2);
|
unicode, 2);
|
||||||
if (nChars == 0) {
|
if (nChars == 0) {
|
||||||
LOG((CLOG_DEBUG2 "KeyID 0x%08x mb->wc mapping failed", id));
|
LOG((CLOG_DEBUG2 "KeyID 0x%08x mb->wc mapping failed", id));
|
||||||
return m_mask;
|
return m_mask;
|
||||||
}
|
}
|
||||||
nChars = WideCharToMultiByte(codePage,
|
nChars = WideCharToMultiByte(codePage,
|
||||||
0,
|
0,
|
||||||
unicode, nChars,
|
unicode, nChars,
|
||||||
multiByte, sizeof(multiByte),
|
multiByte, sizeof(multiByte),
|
||||||
NULL, &error);
|
NULL, &error);
|
||||||
if (nChars == 0 || error) {
|
if (nChars == 0 || error) {
|
||||||
LOG((CLOG_DEBUG2 "KeyID 0x%08x wc->mb mapping failed", id));
|
LOG((CLOG_DEBUG2 "KeyID 0x%08x wc->mb mapping failed", id));
|
||||||
return m_mask;
|
return m_mask;
|
||||||
|
@ -1240,6 +1267,15 @@ CMSWindowsSecondaryScreen::mapToKeystrokes(Keystrokes& keys,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if this is a dead key press then send a release immediately.
|
||||||
|
// the dead key may not be processed correctly if its release
|
||||||
|
// event comes after we release the modifiers.
|
||||||
|
if (action == kPress &&
|
||||||
|
(MapVirtualKey(virtualKey, 2) & 0x80000000lu) != 0) {
|
||||||
|
keystroke.m_press = false;
|
||||||
|
keys.push_back(keystroke);
|
||||||
|
}
|
||||||
|
|
||||||
// add key events to restore the modifier state. apply events in
|
// add key events to restore the modifier state. apply events in
|
||||||
// the reverse order that they're stored in undo.
|
// the reverse order that they're stored in undo.
|
||||||
while (!undo.empty()) {
|
while (!undo.empty()) {
|
||||||
|
|
|
@ -1829,6 +1829,19 @@ const CXWindowsSecondaryScreen::KeySymsMap&
|
||||||
CXWindowsSecondaryScreen::getDecomposedKeySymTable()
|
CXWindowsSecondaryScreen::getDecomposedKeySymTable()
|
||||||
{
|
{
|
||||||
static const KeySym s_rawTable[] = {
|
static const KeySym s_rawTable[] = {
|
||||||
|
// non-dead version of dead keys
|
||||||
|
XK_grave, XK_dead_grave, XK_space, 0,
|
||||||
|
XK_acute, XK_dead_acute, XK_space, 0,
|
||||||
|
XK_asciicircum, XK_dead_circumflex, XK_space, 0,
|
||||||
|
XK_asciitilde, XK_dead_tilde, XK_space, 0,
|
||||||
|
XK_cedilla, XK_dead_cedilla, XK_space, 0,
|
||||||
|
XK_ogonek, XK_dead_ogonek, XK_space, 0,
|
||||||
|
XK_caron, XK_dead_caron, XK_space, 0,
|
||||||
|
XK_abovedot, XK_dead_abovedot, XK_space, 0,
|
||||||
|
XK_doubleacute, XK_dead_doubleacute, XK_space, 0,
|
||||||
|
XK_breve, XK_dead_breve, XK_space, 0,
|
||||||
|
XK_macron, XK_dead_macron, XK_space, 0,
|
||||||
|
|
||||||
// Latin-1 (ISO 8859-1)
|
// Latin-1 (ISO 8859-1)
|
||||||
XK_Agrave, XK_dead_grave, XK_A, 0,
|
XK_Agrave, XK_dead_grave, XK_A, 0,
|
||||||
XK_Aacute, XK_dead_acute, XK_A, 0,
|
XK_Aacute, XK_dead_acute, XK_A, 0,
|
||||||
|
|
Loading…
Reference in New Issue