summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-15 01:00:50 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-02-15 01:00:51 +0100
commitef2ddcf551dec13215cb45cb000731f94b2f8e34 (patch)
treec8810f6ee77a81c3003ccc8783c9d3b17f0b8a5e /src/plugins
parente2cf6ade3535467bc2f21b54b82ed007d5ce279b (diff)
parent501cca2c4b0851cea7133ba56c3a05d71c25ce6d (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm6
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm34
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp1
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp483
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h6
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp18
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp5
11 files changed, 198 insertions, 387 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index 36c11ba8af..830a387fd1 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -269,15 +269,14 @@ struct DeferredDebugHelper
void QCocoaScreen::deliverUpdateRequests()
{
- if (!QGuiApplication::instance())
- return;
+ QMacAutoReleasePool pool;
// The CVDisplayLink callback is a notification that it's a good time to produce a new frame.
// Since the callback is delivered on a separate thread we have to marshal it over to the
// main thread, as Qt requires update requests to be delivered there. This needs to happen
// asynchronously, as otherwise we may end up deadlocking if the main thread calls back
// into any of the CVDisplayLink APIs.
- if (QThread::currentThread() != QGuiApplication::instance()->thread()) {
+ if (!NSThread.isMainThread) {
// We're explicitly not using the data of the GCD source to track the pending updates,
// as the data isn't reset to 0 until after the event handler, and also doesn't update
// during the event handler, both of which we need to track late frames.
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index bf0a1216be..6bedbb556d 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1513,9 +1513,9 @@ void QCocoaWindow::deliverUpdateRequest()
void QCocoaWindow::requestActivateWindow()
{
- NSWindow *window = [m_view window];
- [window makeFirstResponder:m_view];
- [window makeKeyWindow];
+ QMacAutoReleasePool pool;
+ [m_view.window makeFirstResponder:m_view];
+ [m_view.window makeKeyWindow];
}
QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 14f1ca0114..087cb3651f 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -102,40 +102,6 @@ static QCocoaWindow *toPlatformWindow(NSWindow *window)
return QCocoaScreen::mapToNative(maximizedFrame);
}
-#pragma clang diagnostic push
-// NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated, but the
-// NSAnimationContext API that replaces them doesn't handle the use-case of
-// cross-thread screen update synchronization.
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize
-{
- Q_ASSERT(toPlatformWindow(window));
-
- qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize)
- << "- disabling screen updates temporarily";
-
- // There may be separate threads rendering to CA layers in this window,
- // and if any of them do a swap while the resize is still in progress,
- // the visual bounds of that layer will be updated before the visual
- // bounds of the window frame, resulting in flickering while resizing.
-
- // To prevent this we disable screen updates for the whole process until
- // the resize is complete, which makes the whole thing visually atomic.
- NSDisableScreenUpdates();
-
- return frameSize;
-}
-
-- (void)windowDidResize:(NSNotification *)notification
-{
- NSWindow *window = notification.object;
- Q_ASSERT(toPlatformWindow(window));
-
- qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates";
- NSEnableScreenUpdates();
-}
-#pragma clang diagnostic pop
-
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
{
Q_UNUSED(menu);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index 1e4f4e72c8..f154520669 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -63,7 +63,6 @@ QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
#ifndef EGL_EXT_platform_base
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
-typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
#endif
#ifndef EGL_PLATFORM_GBM_KHR
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
index 65a7c4f38a..a93762e5b4 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp
@@ -45,6 +45,10 @@
QT_BEGIN_NAMESPACE
+#ifndef EGL_EXT_platform_base
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
+#endif
+
void QEglFSKmsGbmWindow::resetSurface()
{
QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen());
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 2b96fb3a5e..41655dbd57 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -334,12 +334,8 @@ bool QWindowsContext::initTouch(unsigned integrationOptions)
if (!touchDevice)
return false;
- if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) {
- QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false);
- } else {
- if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
- touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
- }
+ if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch))
+ touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation);
QWindowSystemInterface::registerTouchDevice(touchDevice);
@@ -376,7 +372,6 @@ bool QWindowsContext::initPointer(unsigned integrationOptions)
if (!QWindowsContext::user32dll.supportsPointerApi())
return false;
- QWindowsContext::user32dll.enableMouseInPointer(TRUE);
d->m_systemInfo |= QWindowsContext::SI_SupportsPointer;
return true;
}
@@ -1218,9 +1213,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ExposeEvent:
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam);
case QtWindows::NonClientMouseEvent:
- if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
+ if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
+ return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
+ else
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
- break;
case QtWindows::NonClientPointerEvent:
if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled())
return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
@@ -1246,10 +1242,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
window = window->parent();
if (!window)
return false;
- if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer))
- return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
- else
+ if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer)
return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
+ else
+ return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result);
}
break;
case QtWindows::TouchEvent:
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 203d803a1b..f1960f1585 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -50,9 +50,6 @@
#include "qwindowswindow.h"
#include "qwindowsintegration.h"
#include "qwindowsscreen.h"
-#if QT_CONFIG(draganddrop)
-# include "qwindowsdrag.h"
-#endif
#include <QtGui/qguiapplication.h>
#include <QtGui/qscreen.h>
@@ -78,111 +75,9 @@ enum {
QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD
};
-struct PointerTouchEventInfo {
- QPointer<QWindow> window;
- QList<QWindowSystemInterface::TouchPoint> points;
- Qt::KeyboardModifiers modifiers;
-};
-
-struct PointerTabletEventInfo {
- QPointer<QWindow> window;
- QPointF local;
- QPointF global;
- int device;
- int pointerType;
- Qt::MouseButtons buttons;
- qreal pressure;
- int xTilt;
- int yTilt;
- qreal tangentialPressure;
- qreal rotation;
- int z;
- qint64 uid;
- Qt::KeyboardModifiers modifiers;
-};
-
-static QQueue<PointerTouchEventInfo> touchEventQueue;
-static QQueue<PointerTabletEventInfo> tabletEventQueue;
-
-static void enqueueTouchEvent(QWindow *window,
- const QList<QWindowSystemInterface::TouchPoint> &points,
- Qt::KeyboardModifiers modifiers)
-{
- PointerTouchEventInfo eventInfo;
- eventInfo.window = window;
- eventInfo.points = points;
- eventInfo.modifiers = modifiers;
- touchEventQueue.enqueue(eventInfo);
-}
-
-static void enqueueTabletEvent(QWindow *window, const QPointF &local, const QPointF &global,
- int device, int pointerType, Qt::MouseButtons buttons, qreal pressure,
- int xTilt, int yTilt, qreal tangentialPressure, qreal rotation,
- int z, qint64 uid, Qt::KeyboardModifiers modifiers)
-{
- PointerTabletEventInfo eventInfo;
- eventInfo.window = window;
- eventInfo.local = local;
- eventInfo.global = global;
- eventInfo.device = device;
- eventInfo.pointerType = pointerType;
- eventInfo.buttons = buttons;
- eventInfo.pressure = pressure;
- eventInfo.xTilt = xTilt;
- eventInfo.yTilt = yTilt;
- eventInfo.tangentialPressure = tangentialPressure;
- eventInfo.rotation = rotation;
- eventInfo.z = z;
- eventInfo.uid = uid;
- eventInfo.modifiers = modifiers;
- tabletEventQueue.enqueue(eventInfo);
-}
-
-static void flushTouchEvents(QTouchDevice *touchDevice)
-{
- while (!touchEventQueue.isEmpty()) {
- PointerTouchEventInfo eventInfo = touchEventQueue.dequeue();
- if (eventInfo.window) {
- QWindowSystemInterface::handleTouchEvent(eventInfo.window,
- touchDevice,
- eventInfo.points,
- eventInfo.modifiers);
- }
- }
-}
-
-static void flushTabletEvents()
-{
- while (!tabletEventQueue.isEmpty()) {
- PointerTabletEventInfo eventInfo = tabletEventQueue.dequeue();
- if (eventInfo.window) {
- QWindowSystemInterface::handleTabletEvent(eventInfo.window,
- eventInfo.local,
- eventInfo.global,
- eventInfo.device,
- eventInfo.pointerType,
- eventInfo.buttons,
- eventInfo.pressure,
- eventInfo.xTilt,
- eventInfo.yTilt,
- eventInfo.tangentialPressure,
- eventInfo.rotation,
- eventInfo.z,
- eventInfo.uid,
- eventInfo.modifiers);
- }
- }
-}
-
bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
{
*result = 0;
-
- // If we are inside the move/resize modal loop, let DefWindowProc() handle it (but process NC button release).
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
- if (msg.message != WM_NCPOINTERUP && platformWindow->testFlag(QWindowsWindow::ResizeMoveActive))
- return false;
-
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
POINTER_INPUT_TYPE pointerType;
@@ -191,30 +86,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return false;
}
- m_lastPointerType = pointerType;
-
- // Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow.
- if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) {
- POINTER_INFO pointerInfo;
- if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) {
- qWarning() << "GetPointerInfo() failed:" << qt_error_string();
- return false;
- }
- if (pointerInfo.pointerFlags & (POINTER_FLAG_UP | POINTER_FLAG_DOWN))
- return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo);
- return false;
- }
-
switch (pointerType) {
case QT_PT_POINTER:
case QT_PT_MOUSE:
case QT_PT_TOUCHPAD: {
- POINTER_INFO pointerInfo;
- if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) {
- qWarning() << "GetPointerInfo() failed:" << qt_error_string();
- return false;
- }
- return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo);
+ // Let Mouse/TouchPad be handled using legacy messages.
+ return false;
}
case QT_PT_TOUCH: {
quint32 pointerCount = 0;
@@ -290,76 +167,71 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
return false;
}
-static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton)
-{
- static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping {
- {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton},
- {POINTER_CHANGE_FIRSTBUTTON_UP, Qt::LeftButton},
- {POINTER_CHANGE_SECONDBUTTON_DOWN, Qt::RightButton},
- {POINTER_CHANGE_SECONDBUTTON_UP, Qt::RightButton},
- {POINTER_CHANGE_THIRDBUTTON_DOWN, Qt::MiddleButton},
- {POINTER_CHANGE_THIRDBUTTON_UP, Qt::MiddleButton},
- {POINTER_CHANGE_FOURTHBUTTON_DOWN, Qt::XButton1},
- {POINTER_CHANGE_FOURTHBUTTON_UP, Qt::XButton1},
- {POINTER_CHANGE_FIFTHBUTTON_DOWN, Qt::XButton2},
- {POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2},
- };
-
- static const POINTER_BUTTON_CHANGE_TYPE downChanges[] = {
- POINTER_CHANGE_FIRSTBUTTON_DOWN,
- POINTER_CHANGE_SECONDBUTTON_DOWN,
- POINTER_CHANGE_THIRDBUTTON_DOWN,
- POINTER_CHANGE_FOURTHBUTTON_DOWN,
- POINTER_CHANGE_FIFTHBUTTON_DOWN,
- };
-
- static const POINTER_BUTTON_CHANGE_TYPE upChanges[] = {
- POINTER_CHANGE_FIRSTBUTTON_UP,
- POINTER_CHANGE_SECONDBUTTON_UP,
- POINTER_CHANGE_THIRDBUTTON_UP,
- POINTER_CHANGE_FOURTHBUTTON_UP,
- POINTER_CHANGE_FIFTHBUTTON_UP,
- };
-
- if (!eventType || !mouseButton)
- return;
-
- const bool nonClient = message == WM_NCPOINTERUPDATE ||
- message == WM_NCPOINTERDOWN ||
- message == WM_NCPOINTERUP;
-
- if (std::find(std::begin(downChanges),
- std::end(downChanges), changeType) < std::end(downChanges)) {
- *eventType = nonClient ? QEvent::NonClientAreaMouseButtonPress :
- QEvent::MouseButtonPress;
- } else if (std::find(std::begin(upChanges),
- std::end(upChanges), changeType) < std::end(upChanges)) {
- *eventType = nonClient ? QEvent::NonClientAreaMouseButtonRelease :
- QEvent::MouseButtonRelease;
- } else if (message == WM_POINTERWHEEL || message == WM_POINTERHWHEEL) {
- *eventType = QEvent::Wheel;
- } else {
- *eventType = nonClient ? QEvent::NonClientAreaMouseMove :
- QEvent::MouseMove;
- }
+namespace {
+struct MouseEvent {
+ QEvent::Type type;
+ Qt::MouseButton button;
+};
+} // namespace
- *mouseButton = buttonMapping.value(changeType, Qt::NoButton);
+static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON...
+{
+ return GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? Qt::BackButton : Qt::ForwardButton;
}
-static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags)
+static inline MouseEvent eventFromMsg(const MSG &msg)
{
- 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;
+ switch (msg.message) {
+ case WM_MOUSEMOVE:
+ return {QEvent::MouseMove, Qt::NoButton};
+ case WM_LBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::LeftButton};
+ case WM_LBUTTONUP:
+ return {QEvent::MouseButtonRelease, 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::MouseButtonPress, Qt::MidButton};
+ case WM_RBUTTONDOWN:
+ return {QEvent::MouseButtonPress, Qt::RightButton};
+ case WM_RBUTTONUP:
+ return {QEvent::MouseButtonRelease, Qt::RightButton};
+ case WM_RBUTTONDBLCLK:
+ 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::MouseButtonPress, extraButton(msg.wParam)};
+ case WM_NCMOUSEMOVE:
+ return {QEvent::NonClientAreaMouseMove, Qt::NoButton};
+ case WM_NCLBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton};
+ case WM_NCLBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton};
+ case WM_NCLBUTTONDBLCLK:
+ 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::NonClientAreaMouseButtonPress, Qt::MidButton};
+ case WM_NCRBUTTONDOWN:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
+ case WM_NCRBUTTONUP:
+ return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton};
+ case WM_NCRBUTTONDBLCLK:
+ return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton};
+ default: // WM_MOUSELEAVE
+ break;
+ }
+ return {QEvent::None, Qt::NoButton};
}
static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState)
@@ -419,15 +291,6 @@ static bool isValidWheelReceiver(QWindow *candidate)
return false;
}
-static bool isMenuWindow(QWindow *window)
-{
- if (window)
- if (QObject *fo = window->focusObject())
- if (fo->inherits("QMenu"))
- return true;
- return false;
-}
-
static QTouchDevice *createTouchDevice()
{
const int digitizers = GetSystemMetrics(SM_DIGITIZER);
@@ -553,71 +416,6 @@ void QWindowsPointerHandler::handleEnterLeave(QWindow *window,
m_previousCaptureWindow = hasCapture ? window : nullptr;
}
-bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd,
- QtWindows::WindowsEventType et,
- MSG msg, PVOID vPointerInfo)
-{
- POINTER_INFO *pointerInfo = static_cast<POINTER_INFO *>(vPointerInfo);
- 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 = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags);
- QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
-
- switch (msg.message) {
- case WM_NCPOINTERDOWN:
- case WM_NCPOINTERUP:
- case WM_NCPOINTERUPDATE:
- case WM_POINTERDOWN:
- case WM_POINTERUP:
- case WM_POINTERUPDATE: {
-
- QEvent::Type eventType;
- Qt::MouseButton button;
- getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button);
-
- if (et & QtWindows::NonClientEventFlag) {
- QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
- keyModifiers, Qt::MouseEventNotSynthesized);
- return false; // To allow window dragging, etc.
- } else {
-
- handleCaptureRelease(window, currentWindowUnderPointer, hwnd, eventType, mouseButtons);
- handleEnterLeave(window, currentWindowUnderPointer, globalPos);
-
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType,
- keyModifiers, Qt::MouseEventNotSynthesized);
-
- // The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND
- // has go to through DefWindowProc() for resizing to work, so we return false here,
- // unless the click was on a menu, as it would mess with menu processing.
- return msg.message != WM_POINTERDOWN || isMenuWindow(window);
- }
- }
- 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
- if (msg.message == WM_POINTERHWHEEL)
- delta = -delta;
-
- const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ?
- QPoint(delta, 0) : QPoint(0, delta);
-
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
- return true;
- }
- case WM_POINTERLEAVE:
- return true;
- }
- return false;
-}
-
bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg, PVOID vTouchInfo, quint32 count)
@@ -653,15 +451,14 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
QList<QWindowSystemInterface::TouchPoint> touchPoints;
- bool primaryPointer = false;
- bool pressRelease = false;
-
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
<< __FUNCTION__
<< " message=" << hex << msg.message
<< " count=" << dec << count;
+ Qt::TouchPointStates allStates = 0;
+
for (quint32 i = 0; i < count; ++i) {
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
@@ -670,7 +467,13 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
<< " flags=" << hex << touchInfo[i].pointerInfo.pointerFlags;
QWindowSystemInterface::TouchPoint touchPoint;
- touchPoint.id = touchInfo[i].pointerInfo.pointerId;
+ const quint32 pointerId = touchInfo[i].pointerInfo.pointerId;
+ int id = m_touchInputIDToTouchPointID.value(pointerId, -1);
+ if (id == -1) {
+ id = m_touchInputIDToTouchPointID.size();
+ m_touchInputIDToTouchPointID.insert(pointerId, id);
+ }
+ touchPoint.id = id;
touchPoint.pressure = (touchInfo[i].touchMask & TOUCH_MASK_PRESSURE) ?
touchInfo[i].pressure / 1024.0 : 1.0;
if (m_lastTouchPositions.contains(touchPoint.id))
@@ -691,32 +494,27 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) {
touchPoint.state = Qt::TouchPointPressed;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
- pressRelease = true;
} else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) {
touchPoint.state = Qt::TouchPointReleased;
m_lastTouchPositions.remove(touchPoint.id);
- pressRelease = true;
} else {
touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved;
m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition);
}
- if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY)
- primaryPointer = true;
+ allStates |= touchPoint.state;
touchPoints.append(touchPoint);
// Avoid getting repeated messages for this frame if there are multiple pointerIds
QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
}
- if (primaryPointer && !pressRelease) {
- // Postpone event delivery to avoid hanging inside DoDragDrop().
- // Only the primary pointer will generate mouse messages.
- enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers());
- } else {
- flushTouchEvents(m_touchDevice);
- QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
- QWindowsKeyMapper::queryKeyboardModifiers());
- }
+
+ // all touch points released, forget the ids we've seen.
+ if (allStates == Qt::TouchPointReleased)
+ m_touchInputIDToTouchPointID.clear();
+
+ QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints,
+ QWindowsKeyMapper::queryKeyboardModifiers());
return false; // Allow mouse messages to be generated.
}
@@ -807,10 +605,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
- // Postpone event delivery to avoid hanging inside DoDragDrop().
- enqueueTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
- pressure, xTilt, yTilt, tangentialPressure, rotation, z,
- pointerId, keyModifiers);
+ QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
+ pressure, xTilt, yTilt, tangentialPressure, rotation, z,
+ pointerId, keyModifiers);
return false; // Allow mouse messages to be generated.
}
}
@@ -835,18 +632,46 @@ static inline bool isMouseEventSynthesizedFromPenOrTouch()
return ((::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE);
}
-// Process old-style mouse messages here.
-bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result)
+bool QWindowsPointerHandler::translateMouseWheelEvent(QWindow *window,
+ QWindow *currentWindowUnderPointer,
+ MSG msg,
+ QPoint globalPos,
+ Qt::KeyboardModifiers keyModifiers)
{
- // Generate enqueued events.
- flushTouchEvents(m_touchDevice);
- flushTabletEvents();
+ QWindow *receiver = currentWindowUnderPointer;
+ if (!isValidWheelReceiver(receiver))
+ receiver = window;
+ if (!isValidWheelReceiver(receiver))
+ 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);
+
+ QPoint localPos = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos);
+
+ QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
+ return true;
+}
+
+// Process legacy mouse messages here.
+bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
+ HWND hwnd,
+ QtWindows::WindowsEventType et,
+ MSG msg,
+ LRESULT *result)
+{
*result = 0;
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);
@@ -857,46 +682,39 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
+ QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
- // Handle "press and hold for right-clicking".
- // We have to synthesize it here as it only comes from Windows as a fake RMB.
- // MS docs say we could use bit 7 from extraInfo to distinguish pen from touch,
- // but on the Surface it is set for both. So we use the last pointer type.
- if (isMouseEventSynthesizedFromPenOrTouch()) {
- if ((msg.message == WM_RBUTTONDOWN || msg.message == WM_RBUTTONUP)
- && (((m_lastPointerType == QT_PT_PEN)
- && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents))
- || ((m_lastPointerType == QT_PT_TOUCH)
- && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)))) {
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::RightButton,
- (msg.message == WM_RBUTTONDOWN) ? QEvent::MouseButtonPress
- : QEvent::MouseButtonRelease,
- keyModifiers, Qt::MouseEventSynthesizedBySystem);
- }
- // Messages synthesized from touch/pen are only used for flushing queues and press&hold.
- return false;
+ if (et == QtWindows::MouseWheelEvent)
+ return translateMouseWheelEvent(window, currentWindowUnderPointer, msg, globalPos, keyModifiers);
+
+ // Windows sends a mouse move with no buttons pressed to signal "Enter"
+ // when a window is shown over the cursor. Discard the event and only use
+ // it for generating QEvent::Enter to be consistent with other platforms -
+ // X11 and macOS.
+ bool discardEvent = false;
+ if (msg.message == WM_MOUSEMOVE) {
+ static QPoint lastMouseMovePos;
+ if (msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos))
+ discardEvent = true;
+ lastMouseMovePos = globalPos;
}
- 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;
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+ if (isMouseEventSynthesizedFromPenOrTouch()) {
+ if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)
+ return false;
+ source = Qt::MouseEventSynthesizedBySystem;
+ }
- const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ?
- QPoint(delta, 0) : QPoint(0, delta);
+ const MouseEvent mouseEvent = eventFromMsg(msg);
- QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers);
- return true;
+ if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) {
+ QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons,
+ mouseEvent.button, mouseEvent.type, keyModifiers, source);
+ return false; // Allow further event processing
}
if (msg.message == WM_MOUSELEAVE) {
-
if (window == m_currentWindow) {
QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow;
qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget;
@@ -904,14 +722,21 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
m_windowUnderPointer = nullptr;
m_currentWindow = nullptr;
}
+ return true;
+ }
- } else if (msg.message == WM_MOUSEMOVE) {
+ handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons);
+ handleEnterLeave(window, currentWindowUnderPointer, globalPos);
- QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
- handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons);
- handleEnterLeave(window, currentWindowUnderPointer, globalPos);
+ if (!discardEvent && mouseEvent.type != QEvent::None) {
+ QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons,
+ mouseEvent.button, mouseEvent.type, keyModifiers, source);
}
- return false;
+
+ // QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND
+ // is sent for unhandled WM_XBUTTONDOWN.
+ return (msg.message != WM_XBUTTONUP && msg.message != WM_XBUTTONDOWN && msg.message != WM_XBUTTONDBLCLK)
+ || QWindowSystemInterface::flushWindowSystemEvents();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index ec3179e821..aebef062bc 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -66,19 +66,19 @@ public:
void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; }
private:
- bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo);
bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count);
bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo);
+ bool translateMouseWheelEvent(QWindow *window, QWindow *currentWindowUnderPointer, MSG msg, QPoint globalPos, Qt::KeyboardModifiers keyModifiers);
void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons);
void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos);
QTouchDevice *m_touchDevice = nullptr;
QHash<int, QPointF> m_lastTouchPositions;
+ QHash<DWORD, int> m_touchInputIDToTouchPointID;
QPointer<QWindow> m_windowUnderPointer;
QPointer<QWindow> m_currentWindow;
QWindow *m_previousCaptureWindow = nullptr;
bool m_needsEnterOnPointerUpdate = false;
- DWORD m_lastPointerType = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 7f1854c601..e611c7be24 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -511,6 +511,7 @@ public:
QWindow *currentPressWindow = nullptr;
QWindow *currentTargetWindow = nullptr;
bool firstMouseMove = true;
+ bool resizePending = false;
};
// To be called from the XAML thread
@@ -1402,6 +1403,18 @@ void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransitio
Qt::NoModifier);
}
+void QWinRTScreen::setResizePending()
+{
+ Q_D(QWinRTScreen);
+ d->resizePending = true;
+}
+
+bool QWinRTScreen::resizePending() const
+{
+ Q_D(const QWinRTScreen);
+ return d->resizePending;
+}
+
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{
Q_D(QWinRTScreen);
@@ -1507,7 +1520,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent
return onPointerUpdated(nullptr, args);
}
-HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *)
+HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *w, IInspectable *)
{
Q_D(QWinRTScreen);
@@ -1527,6 +1540,9 @@ HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *)
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
+ // If we "emulate" a resize, w will be nullptr.Checking w shows whether it's a real resize
+ if (w)
+ d->resizePending = false;
return S_OK;
}
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
index e28cfd8cc8..63c254940d 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -136,6 +136,9 @@ public:
void emulateMouseMove(const QPointF &point, MousePositionTransition transition);
+ void setResizePending();
+ bool resizePending() const;
+
private:
void handleExpose();
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 83c3715bfd..73816b6512 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -225,7 +225,8 @@ bool QWinRTWindow::isActive() const
bool QWinRTWindow::isExposed() const
{
- const bool exposed = isActive();
+ Q_D(const QWinRTWindow);
+ const bool exposed = isActive() && !d->screen->resizePending();
return exposed;
}
@@ -360,6 +361,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state)
qCDebug(lcQpaWindows) << "Failed to enter full screen mode.";
return;
}
+ d->screen->setResizePending();
d->state = state;
return;
}
@@ -384,6 +386,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state)
qCDebug(lcQpaWindows) << "Failed to exit full screen mode.";
return;
}
+ d->screen->setResizePending();
}
if (d->state & Qt::WindowMinimized || state == Qt::WindowNoState || state == Qt::WindowActive)