From 9388bbe4bdc366760c0ee5953d5f2157c51a8e68 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 19 Oct 2015 17:18:19 +0200 Subject: Windows: Implement QPlatformInputContext::locale(). Initialize locale from current keyboard value and listen to WM_INPUTLANGCHANGE. Task-number: QTBUG-48772 Change-Id: I53b6ef4e2cf538bb81b41ea497ed0cb66991b104 Reviewed-by: Liang Qi Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscontext.cpp | 12 ++++++-- .../platforms/windows/qwindowsinputcontext.cpp | 33 ++++++++++++++++++++-- .../platforms/windows/qwindowsinputcontext.h | 6 ++++ 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4ec34c05bd..4d18e7ea58 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -860,6 +860,11 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) return result; } +static inline QWindowsInputContext *windowsInputContext() +{ + return qobject_cast(QWindowsIntegration::instance()->inputContext()); +} + /*! \brief Main windows procedure registered for windows. @@ -909,8 +914,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } } if (et & QtWindows::InputMethodEventFlag) { - QWindowsInputContext *windowsInputContext = - qobject_cast(QWindowsIntegration::instance()->inputContext()); + QWindowsInputContext *windowsInputContext = ::windowsInputContext(); // Disable IME assuming this is a special implementation hooking into keyboard input. // "Real" IME implementations should use a native event filter intercepting IME events. if (!windowsInputContext) { @@ -1006,11 +1010,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, } switch (et) { + case QtWindows::KeyboardLayoutChangeEvent: + if (QWindowsInputContext *wic = windowsInputContext()) + wic->handleInputLanguageChanged(wParam, lParam); // fallthrough intended. case QtWindows::KeyDownEvent: case QtWindows::KeyEvent: case QtWindows::InputMethodKeyEvent: case QtWindows::InputMethodKeyDownEvent: - case QtWindows::KeyboardLayoutChangeEvent: case QtWindows::AppCommandEvent: #if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER) return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index e016b84bba..7e1cc563cb 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -84,6 +84,18 @@ static inline void imeNotifyCancelComposition(HWND hwnd) ImmReleaseContext(hwnd, himc); } +static inline LCID languageIdFromLocaleId(LCID localeId) +{ + return localeId & 0xFFFF; +} + +static inline LCID currentInputLanguageId() +{ + return languageIdFromLocaleId(reinterpret_cast(GetKeyboardLayout(0))); +} + +Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp + /*! \class QWindowsInputContext \brief Windows Input context implementation @@ -153,7 +165,9 @@ QWindowsInputContext::CompositionContext::CompositionContext() : QWindowsInputContext::QWindowsInputContext() : m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")), - m_endCompositionRecursionGuard(false) + m_endCompositionRecursionGuard(false), + m_languageId(currentInputLanguageId()), + m_locale(qt_localeFromLCID(m_languageId)) { connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QWindowsInputContext::cursorRectChanged); @@ -371,7 +385,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd) QWindow *window = QGuiApplication::focusWindow(); if (!window) return false; - qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window; + qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window << "language=" << m_languageId; if (!fo || QWindowsWindow::handleOf(window) != hwnd) return false; initContext(hwnd, fo); @@ -555,6 +569,21 @@ bool QWindowsInputContext::handleIME_Request(WPARAM wParam, return false; } +void QWindowsInputContext::handleInputLanguageChanged(WPARAM wparam, LPARAM lparam) +{ + const LCID newLanguageId = languageIdFromLocaleId(lparam); + if (newLanguageId == m_languageId) + return; + const LCID oldLanguageId = m_languageId; + m_languageId = newLanguageId; + m_locale = qt_localeFromLCID(m_languageId); + emitLocaleChanged(); + + qCDebug(lcQpaInputMethods) << __FUNCTION__ << hex << showbase + << oldLanguageId << "->" << newLanguageId << "Character set:" + << DWORD(wparam) << dec << noshowbase << m_locale; +} + /*! \brief Determines the string for reconversion with selection. diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h index eb4e3a3faa..636d481e70 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.h +++ b/src/plugins/platforms/windows/qwindowsinputcontext.h @@ -36,6 +36,7 @@ #include "qtwindows_additional.h" +#include #include #include @@ -66,6 +67,8 @@ public: static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled); bool hasCapability(Capability capability) const Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE { return m_locale; } + void reset() Q_DECL_OVERRIDE; void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE; void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE; @@ -79,6 +82,7 @@ public: int reconvertString(RECONVERTSTRING *reconv); bool handleIME_Request(WPARAM wparam, LPARAM lparam, LRESULT *result); + void handleInputLanguageChanged(WPARAM wparam, LPARAM lparam); private slots: void cursorRectChanged(); @@ -94,6 +98,8 @@ private: static HIMC m_defaultContext; CompositionContext m_compositionContext; bool m_endCompositionRecursionGuard; + LCID m_languageId; + QLocale m_locale; }; QT_END_NAMESPACE -- cgit v1.2.3