From 35069301f048eed21a27f89b6495d56c44f2b55d Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 30 Oct 2018 17:58:17 +0100 Subject: Windows QPA: Fix incorrect button state reporting for touchpad The current state of (emulated) mouse buttons was being incorrectly reported for touchpad events under some conditions. In the handling of pointer messages, GetAsyncKeyState() was being used to retrieve the mouse button state. However, it does not seem to work always with all touchpads. Furthermore, its use is not necessary, since the button state information comes as a set of flags with the pointer message itself. This change makes the handler use these flags instead. Fixes: QTBUG-71470 Change-Id: Ie2e35bd80778ef74db672604a0f2af659785efbf Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowspointerhandler.cpp | 53 ++++++++++++++-------- .../platforms/windows/qwindowspointerhandler.h | 1 - 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 2b6c696979..4d3e2f71ec 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -336,6 +336,38 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp *mouseButton = buttonMapping.value(changeType, Qt::NoButton); } +static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags) +{ + Qt::MouseButtons result = Qt::NoButton; + if (pointerFlags & POINTER_FLAG_FIRSTBUTTON) + result |= Qt::LeftButton; + if (pointerFlags & POINTER_FLAG_SECONDBUTTON) + result |= Qt::RightButton; + if (pointerFlags & POINTER_FLAG_THIRDBUTTON) + result |= Qt::MiddleButton; + if (pointerFlags & POINTER_FLAG_FOURTHBUTTON) + result |= Qt::XButton1; + if (pointerFlags & POINTER_FLAG_FIFTHBUTTON) + result |= Qt::XButton2; + return result; +} + +static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState) +{ + Qt::MouseButtons result = Qt::NoButton; + if (keyState & MK_LBUTTON) + result |= Qt::LeftButton; + if (keyState & MK_RBUTTON) + result |= Qt::RightButton; + if (keyState & MK_MBUTTON) + result |= Qt::MiddleButton; + if (keyState & MK_XBUTTON1) + result |= Qt::XButton1; + if (keyState & MK_XBUTTON2) + result |= Qt::XButton2; + return result; +} + static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) { QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); @@ -405,23 +437,6 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice() return m_touchDevice; } -Qt::MouseButtons QWindowsPointerHandler::queryMouseButtons() -{ - Qt::MouseButtons result = 0; - const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON); - if (GetAsyncKeyState(VK_LBUTTON) < 0) - result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton; - if (GetAsyncKeyState(VK_RBUTTON) < 0) - result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton; - if (GetAsyncKeyState(VK_MBUTTON) < 0) - result |= Qt::MidButton; - if (GetAsyncKeyState(VK_XBUTTON1) < 0) - result |= Qt::XButton1; - if (GetAsyncKeyState(VK_XBUTTON2) < 0) - result |= Qt::XButton2; - return result; -} - bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo) @@ -430,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h const QPoint globalPos = QPoint(pointerInfo->ptPixelLocation.x, pointerInfo->ptPixelLocation.y); const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - const Qt::MouseButtons mouseButtons = queryMouseButtons(); + const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags); QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); QWindowsWindow *platformWindow = static_cast(window->handle()); @@ -788,7 +803,7 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = currentWindowUnderPointer; } - const Qt::MouseButtons mouseButtons = queryMouseButtons(); + const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); if (!discardEvent) QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove, diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index c4d0e0ce4a..3861ebf919 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -61,7 +61,6 @@ public: bool translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result); QTouchDevice *touchDevice() const { return m_touchDevice; } QTouchDevice *ensureTouchDevice(); - Qt::MouseButtons queryMouseButtons(); QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); } void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; } -- cgit v1.2.3 From d9200fcac58a9347decd417c217c18b7e34471ec Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 13 Nov 2018 20:22:20 +0100 Subject: Windows QPA: Fix broken focus for native child windows This issue was caused by missing logic in the implementation of the pointer message handler, necessary to support "click to focus" for native child windows. Fixes: QTBUG-71352 Change-Id: I2e261caa8dfab096647799ec1e7d781bec40654e Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 4d3e2f71ec..3c7372958f 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -467,6 +467,11 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h keyModifiers, Qt::MouseEventNotSynthesized); return false; // To allow window dragging, etc. } else { + if (eventType == QEvent::MouseButtonPress) { + // Implement "Click to focus" for native child windows (unless it is a native widget window). + if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window) + window->requestActivate(); + } if (currentWindowUnderPointer != m_windowUnderPointer) { if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) { QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); -- cgit v1.2.3 From ad2c7f588321f8c671cb9419f90a1e24887ed562 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 14 Nov 2018 18:10:25 +0100 Subject: Windows QPA: Fix input context visibility status QWindowsInputContext::isInputPanelVisible() was ignoring the visibility status of the IME, only returning the status of the Win10 virtual keyboard. This issue caused qtwebengine to try to show the IME multiple times, breaking Asian languages input. Task-number: QTBUG-71753 Change-Id: Iaa4cef37b7dc98a9e0a787750a34d2e98a87a777 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Alexandru Croitor Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsinputcontext.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 30da0da1de..d1e99c037b 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -242,7 +242,18 @@ QRectF QWindowsInputContext::keyboardRect() const bool QWindowsInputContext::isInputPanelVisible() const { HWND hwnd = getVirtualKeyboardWindowHandle(); - return hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd); + if (hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd)) + return true; + // check if the Input Method Editor is open + if (inputMethodAccepted()) { + if (QWindow *window = QGuiApplication::focusWindow()) { + if (QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window)) { + if (HIMC himc = ImmGetContext(platformWindow->handle())) + return ImmGetOpenStatus(himc); + } + } + } + return false; } void QWindowsInputContext::showInputPanel() -- cgit v1.2.3