summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp5
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp47
4 files changed, 31 insertions, 27 deletions
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 418074dc7a..65ca6b0dcb 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -831,6 +831,11 @@ QString decodeMSG(const MSG& msg)
}
break;
#endif
+#ifdef WM_INPUTLANGCHANGE
+ case WM_INPUTLANGCHANGE:
+ parameters = QStringLiteral("Keyboard layout changed");
+ break;
+#endif // WM_INPUTLANGCHANGE
#ifdef WM_NCACTIVATE
case WM_NCACTIVATE:
{
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index f6ed9447ef..7b574b0a56 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -93,6 +93,7 @@ enum WindowsEventType // Simplify event types
NonClientHitTest = NonClientEventFlag + 2,
KeyEvent = KeyEventFlag + 1,
KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
+ KeyboardLayoutChangeEvent = KeyEventFlag + 2,
InputMethodKeyEvent = InputMethodEventFlag + KeyEventFlag + 1,
InputMethodKeyDownEvent = InputMethodEventFlag + KeyEventFlag + KeyDownEventFlag + 1,
ClipboardEvent = ClipboardEventFlag + 1,
@@ -165,6 +166,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::InputMethodKeyEvent;
case WM_IME_KEYDOWN:
return QtWindows::InputMethodKeyDownEvent;
+#ifdef WM_INPUTLANGCHANGE
+ case WM_INPUTLANGCHANGE:
+ return QtWindows::KeyboardLayoutChangeEvent;
+#endif // WM_INPUTLANGCHANGE
case WM_TOUCH:
return QtWindows::TouchEvent;
case WM_CHANGECBCHAIN:
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 85b03673ac..174b3312d2 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -842,6 +842,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::KeyEvent:
case QtWindows::InputMethodKeyEvent:
case QtWindows::InputMethodKeyDownEvent:
+ case QtWindows::KeyboardLayoutChangeEvent:
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
return platformSessionManager()->isInterractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
#else
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 47c136991a..994128738b 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -574,7 +574,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
{
unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
GetKeyboardState(kbdBuffer);
- quint32 scancode = (msg.lParam >> 16) & 0xfff;
+ const quint32 scancode = (msg.lParam >> 16) & 0xff;
updatePossibleKeyCodes(kbdBuffer, scancode, msg.wParam);
}
@@ -742,12 +742,21 @@ bool QWindowsKeyMapper::translateKeyEvent(QWindow *widget, HWND hwnd,
const MSG &msg, LRESULT *result)
{
*result = 0;
+
+ // Reset layout map when system keyboard layout is changed
+ if (msg.message == WM_INPUTLANGCHANGE) {
+ deleteLayouts();
+ return true;
+ }
+
+ // Add this key to the keymap if it is not present yet.
+ updateKeyMap(msg);
+
MSG peekedMsg;
// consume dead chars?(for example, typing '`','a' resulting in a-accent).
if (PeekMessage(&peekedMsg, hwnd, 0, 0, PM_NOREMOVE) && peekedMsg.message == WM_DEADCHAR)
return true;
- if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
- updateKeyMap(msg);
+
return translateKeyEventInternal(widget, msg, false);
}
@@ -755,9 +764,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
{
const int msgType = msg.message;
- const quint32 scancode = (msg.lParam >> 16) & 0xfff;
- const quint32 vk_key = MapVirtualKey(scancode, 1);
- const bool isNumpad = (msg.wParam >= VK_NUMPAD0 && msg.wParam <= VK_NUMPAD9);
+ const quint32 scancode = (msg.lParam >> 16) & 0xff;
+ const quint32 vk_key = msg.wParam;
quint32 nModifiers = 0;
QWindow *receiver = m_keyGrabber ? m_keyGrabber : window;
@@ -786,10 +794,6 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
state |= (nModifiers & AltAny ? int(Qt::AltModifier) : 0);
state |= (nModifiers & MetaAny ? int(Qt::MetaModifier) : 0);
- // Now we know enough to either have MapVirtualKey or our own keymap tell us if it's a deadkey
- const bool isDeadKey = isADeadKey(msg.wParam, state)
- || MapVirtualKey(msg.wParam, 2) & 0x80000000;
-
// A multi-character key or a Input method character
// not found by our look-ahead
if (msgType == WM_CHAR || msgType == WM_IME_CHAR) {
@@ -849,23 +853,12 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
return true;
// Translate VK_* (native) -> Key_* (Qt) keys
- // If it's a dead key, we cannot use the toKeyOrUnicode() function, since that will change
- // the internal state of the keyboard driver, resulting in that dead keys no longer works.
- // ..also if we're typing numbers on the keypad, while holding down the Alt modifier.
- int code = 0;
- if (isNumpad && (nModifiers & AltAny)) {
- code = winceKeyBend(msg.wParam);
- } else if (!isDeadKey) {
- // QTBUG-8764, QTBUG-10032
- // Can't call toKeyOrUnicode because that would call ToUnicode, and, if a dead key
- // is pressed at the moment, Windows would NOT use it to compose a character for the next
- // WM_CHAR event.
-
- // Instead, use MapVirtualKey, which will provide adequate values.
- code = MapVirtualKey(msg.wParam, MAPVK_VK_TO_CHAR);
- if (code < 0x20 || code == 0x7f) // The same logic as in toKeyOrUnicode()
- code = winceKeyBend(msg.wParam);
- }
+ int modifiersIndex = 0;
+ modifiersIndex |= (nModifiers & ShiftAny ? 0x1 : 0);
+ modifiersIndex |= (nModifiers & ControlAny ? 0x2 : 0);
+ modifiersIndex |= (nModifiers & AltAny ? 0x4 : 0);
+
+ int code = keyLayout[vk_key].qtKey[modifiersIndex];
// Invert state logic:
// If the key actually pressed is a modifier key, then we remove its modifier key from the