From c0538857358e57c1551f7d10c07a9bb80d848cd7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 Oct 2018 08:19:04 +0200 Subject: Windows/QPA: Fix receiving mouse clicks after double clicks in QQuickWidget The Qt QPA does not handle native double clicks as such; change the plugin not to send them. For Ink, remove the doubleclick detection. For the old code path, map them to Press. Fixes: QTBUG-70999 Change-Id: I54b858f9e146bf325a861554d5ef74143db7d2b7 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowsmousehandler.cpp | 16 ++++++------- .../platforms/windows/qwindowspointerhandler.cpp | 26 ++-------------------- 2 files changed, 10 insertions(+), 32 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index c1c275144f..fcdd179a31 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -207,26 +207,26 @@ static inline MouseEvent eventFromMsg(const MSG &msg) return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_LBUTTONUP: return {QEvent::MouseButtonRelease, Qt::LeftButton}; - case WM_LBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::LeftButton}; + case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press + return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_MBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_MBUTTONUP: return {QEvent::MouseButtonRelease, Qt::MidButton}; case WM_MBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::MidButton}; + return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_RBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_RBUTTONUP: return {QEvent::MouseButtonRelease, Qt::RightButton}; case WM_RBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::RightButton}; + return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_XBUTTONDOWN: return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_XBUTTONUP: return {QEvent::MouseButtonRelease, extraButton(msg.wParam)}; case WM_XBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)}; + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_NCMOUSEMOVE: return {QEvent::NonClientAreaMouseMove, Qt::NoButton}; case WM_NCLBUTTONDOWN: @@ -234,19 +234,19 @@ static inline MouseEvent eventFromMsg(const MSG &msg) case WM_NCLBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton}; case WM_NCLBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; case WM_NCMBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCMBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton}; case WM_NCMBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCRBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; case WM_NCRBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton}; case WM_NCRBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; default: // WM_MOUSELEAVE break; } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 09eadb247a..21dc0cd577 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -280,7 +280,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } -static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QPoint globalPos, QEvent::Type *eventType, Qt::MouseButton *mouseButton) +static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton) { static const QHash buttonMapping { {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton}, @@ -334,28 +334,6 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp } *mouseButton = buttonMapping.value(changeType, Qt::NoButton); - - // Pointer messages lack a double click indicator. Check if this is the case here. - if (*eventType == QEvent::MouseButtonPress || - *eventType == QEvent::NonClientAreaMouseButtonPress) { - static LONG lastTime = 0; - static Qt::MouseButton lastButton = Qt::NoButton; - static QEvent::Type lastEvent = QEvent::None; - static QPoint lastPos; - LONG messageTime = GetMessageTime(); - if (*mouseButton == lastButton - && *eventType == lastEvent - && messageTime - lastTime < (LONG)GetDoubleClickTime() - && qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK) - && qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) { - *eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick : - QEvent::MouseButtonDblClick; - } - lastTime = messageTime; - lastButton = *mouseButton; - lastEvent = *eventType; - lastPos = globalPos; - } } static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) @@ -467,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h QEvent::Type eventType; Qt::MouseButton button; - getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, globalPos, &eventType, &button); + getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button); if (et & QtWindows::NonClientEventFlag) { QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, -- cgit v1.2.3 From ebfad73b4e44fe6db8059200da105b4b87888718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 16:29:29 +0200 Subject: macOS: Fix NSOpenGLContext view association check The expression "m_context.view = view" always evaluates to the view, so the check was flawed. Change-Id: Icef4ba5244975ccd78a151c7d40c53b2364c6148 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 1e1b3907ed..1cd77a22e4 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -414,7 +414,8 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) // have the same effect as an update. // Now we are ready to associate the view with the context - if ((m_context.view = view) != view) { + m_context.view = view; + if (m_context.view != view) { qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context; m_updateObservers.clear(); return false; -- cgit v1.2.3 From 88fe7c8cad0bb8e9aee1373c7a7a24d1e4be24ca Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 24 Oct 2018 14:22:43 +0200 Subject: Windows QPA: Fix 2-finger scroll not working with some touchpads It seems some touchpads only send legacy WM_MOUSEWHEEL/WM_MOUSEHWHEEL messages for 2-finger scrolling, instead of WM_POINTERWHEEL/ WM_POINTERHWHEEL, even after EnableMouseInPointer(TRUE), in spite of sending the expected pointer messages for normal pointer movement/taps. This change adds a workaround to handle legacy wheel messages even when in pointer mode. Task-number: QTBUG-71257 Change-Id: Ib360051147c4521751a5b91d90fa7657496777fa Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowspointerhandler.cpp | 43 +++++++++++++++++----- 1 file changed, 34 insertions(+), 9 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 21dc0cd577..2b6c696979 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -484,6 +484,9 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h case WM_POINTERHWHEEL: case WM_POINTERWHEEL: { + if (!isValidWheelReceiver(window)) + return true; + int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); // Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL @@ -493,8 +496,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ? QPoint(delta, 0) : QPoint(0, delta); - if (isValidWheelReceiver(window)) - QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); return true; } case WM_POINTERLEAVE: @@ -508,7 +510,6 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, MSG msg, PVOID vTouchInfo, quint32 count) { Q_UNUSED(hwnd); - Q_UNUSED(et); if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. @@ -707,21 +708,46 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin // Process old-style mouse messages here. bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { - Q_UNUSED(et); - // Generate enqueued events. flushTouchEvents(m_touchDevice); flushTabletEvents(); *result = 0; - if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) + if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) return false; - const QPoint localPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); - const QPoint globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, localPos); + const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + QPoint localPos; + QPoint globalPos; + if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) { + globalPos = eventPos; + localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos); + } else { + localPos = eventPos; + globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, eventPos); + } + const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); QWindowsWindow *platformWindow = static_cast(window->handle()); + if (et == QtWindows::MouseWheelEvent) { + + if (!isValidWheelReceiver(window)) + return true; + + int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); + + // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL + if (msg.message == WM_MOUSEHWHEEL) + delta = -delta; + + const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ? + QPoint(delta, 0) : QPoint(0, delta); + + QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + return true; + } + if (msg.message == WM_MOUSELEAVE) { if (window == m_currentWindow) { QWindowSystemInterface::handleLeaveEvent(window); @@ -762,7 +788,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = currentWindowUnderPointer; } - const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); const Qt::MouseButtons mouseButtons = queryMouseButtons(); if (!discardEvent) -- cgit v1.2.3 From 8e1c8076282f87a8d19f73feb1bb5baf068de1e1 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 24 Oct 2018 11:11:21 +0200 Subject: xcb: fix unresponsive mouse clicks after VT switch This patch amends d67214302f269242ae3d8d2b962fd91ec42c979e. The issue was caused by mistakenly interchanging m_hasXRender <-> m_hasXRandr. Also renamed selectXRandrEvents() -> xrandrSelectEvents() to be more consistent with xi2Select*() API. And moved the xrandrSelectEvents() to QXcbConnection ctor for the same reason. Fixes: QTBUG-71305 Change-Id: I26f9bac3ae1f997f53134eb97f3569fb6d3c13fe Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +++ src/plugins/platforms/xcb/qxcbconnection.h | 2 +- src/plugins/platforms/xcb/qxcbconnection_basic.cpp | 4 ++-- src/plugins/platforms/xcb/qxcbconnection_screens.cpp | 6 ++---- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 9e857ea2ff..45f096a13a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -105,6 +105,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower(); + if (hasXRandr()) + xrandrSelectEvents(); + initializeScreens(); #if QT_CONFIG(xcb_xinput) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 49e79ec3fd..5d53b97d37 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -250,7 +250,7 @@ protected: bool event(QEvent *e) override; private: - void selectXRandrEvents(); + void xrandrSelectEvents(); QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const; QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const; QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const; diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index 7bed3c8937..b8335d1240 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -308,7 +308,7 @@ void QXcbBasicConnection::initializeXRandr() return; } - m_hasXRender = true; + m_hasXRandr = true; m_xrenderVersion.first = xrenderQuery->major_version; m_xrenderVersion.second = xrenderQuery->minor_version; #endif @@ -358,7 +358,7 @@ void QXcbBasicConnection::initializeXRender() return; } - m_hasXRandr = true; + m_hasXRender = true; m_xrandrFirstEvent = reply->first_event; } diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index 4c380bf39f..fe9e0be86d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -46,7 +46,7 @@ #include -void QXcbConnection::selectXRandrEvents() +void QXcbConnection::xrandrSelectEvents() { xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(setup()); for (; rootIter.rem; xcb_screen_next(&rootIter)) { @@ -270,8 +270,6 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) void QXcbConnection::initializeScreens() { - selectXRandrEvents(); - xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup()); int xcbScreenNumber = 0; // screen number in the xcb sense QXcbScreen *primaryScreen = nullptr; @@ -284,7 +282,7 @@ void QXcbConnection::initializeScreens() QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); m_virtualDesktops.append(virtualDesktop); QList siblings; - if (hasXRender()) { + if (hasXRandr()) { // RRGetScreenResourcesCurrent is fast but it may return nothing if the // configuration is not initialized wrt to the hardware. We should call // RRGetScreenResources in this case. -- cgit v1.2.3 From 269172037db11d6e62bcef2d5c7491af9244f203 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 18 Oct 2018 10:20:42 +1000 Subject: wasm: use maintainTimers instead of processEvents for touch callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If39cdeedef60a47c0ba1afbab6adf1668bf5d0d6 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 23251fd610..a3fdcd1025 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -546,7 +546,7 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven else QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier); - QCoreApplication::processEvents(); + QWasmEventDispatcher::maintainTimers(); return 1; } -- cgit v1.2.3 From d02fed67814a3cb8f28a4f0ec61e075858fce238 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Mon, 1 Oct 2018 09:16:28 +1000 Subject: macOS: restore hidden popup windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to to explicitly unhide popup windows that were previously explicitly hidden by applicationWillHide, so that their visibility will be effectively restored when the application is unhidden (otherwise the windows are gone forever even though their internal visibility is set to true). Change-Id: I4dbd209b07f769cc815851b40c41db0739ca2dc9 Task-number: QTBUG-71014 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoaapplicationdelegate.mm | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 221a8b0866..44ab16d300 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -86,6 +86,7 @@ #include #include "qt_mac_p.h" #include +#include QT_USE_NAMESPACE @@ -93,6 +94,7 @@ QT_USE_NAMESPACE bool startedQuit; NSObject *reflectionDelegate; bool inLaunch; + QWindowList hiddenWindows; } + (instancetype)sharedDelegate @@ -322,12 +324,28 @@ QT_USE_NAMESPACE // fact that the application itself is hidden, which will cause a problem when // the application is made visible again. const QWindowList topLevelWindows = QGuiApplication::topLevelWindows(); - for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) { - if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) + for (QWindow *topLevelWindow : topLevelWindows) { + if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) { topLevelWindow->hide(); + + if ((topLevelWindow->type() & Qt::Tool) == Qt::Tool) + hiddenWindows << topLevelWindow; + } } } +- (void)applicationDidUnhide:(NSNotification *)notification +{ + if (reflectionDelegate + && [reflectionDelegate respondsToSelector:@selector(applicationDidUnhide:)]) + [reflectionDelegate applicationDidUnhide:notification]; + + for (QWindow *window : qAsConst(hiddenWindows)) + window->show(); + + hiddenWindows.clear(); +} + - (void)applicationDidBecomeActive:(NSNotification *)notification { if (reflectionDelegate -- cgit v1.2.3