summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-23 10:13:28 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-23 10:13:29 +0100
commite3da05f39a5b000bbb6194396d688bf26af771fd (patch)
tree6b1e0b84a2ef9b7abdd465c0aecb5688fcb40f1a /src/plugins/platforms
parent0c007a87be88f44151616b7251cfed5508913e0f (diff)
parent9822d57d858068cfe5a07281ef069ef8c4c7b7b3 (diff)
Merge remote-tracking branch 'origin/5.12.1' into 5.12
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp38
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.cpp221
-rw-r--r--src/plugins/platforms/windows/qwindowspointerhandler.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.cpp8
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro4
7 files changed, 187 insertions, 97 deletions
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 7b3546f9bb..cdc52e1cb4 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -99,13 +99,12 @@ static jfieldID m_selectionStartFieldID = 0;
static jfieldID m_startOffsetFieldID = 0;
static jfieldID m_textFieldID = 0;
-Q_DECLARE_METATYPE(std::function<void()>)
-
static void runOnQtThread(const std::function<void()> &func)
{
- const bool block = QGuiApplication::applicationState() >= Qt::ApplicationInactive;
- QMetaObject::invokeMethod(m_androidInputContext, "safeCall",
- block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, Q_ARG(std::function<void()>, func));
+ AndroidDeadlockProtector protector;
+ if (!protector.acquire())
+ return;
+ QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function<void()>, func));
}
static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
@@ -116,7 +115,7 @@ static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ BEGINBATCH");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&res]{res = m_androidInputContext->beginBatchEdit();});
return res;
}
@@ -130,7 +129,7 @@ static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
qDebug("@@@ ENDBATCH");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&res]{res = m_androidInputContext->endBatchEdit();});
return res;
}
@@ -149,7 +148,7 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ COMMIT" << str << newCursorPosition;
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->commitText(str, newCursorPosition);});
return res;
}
@@ -162,7 +161,7 @@ static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint le
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ DELETE" << leftLength << rightLength;
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->deleteSurroundingText(leftLength, rightLength);});
return res;
}
@@ -175,7 +174,7 @@ static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ FINISH");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->finishComposingText();});
return res;
}
@@ -185,7 +184,7 @@ static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes)
if (!m_androidInputContext)
return 0;
- jboolean res;
+ jint res = 0;
runOnQtThread([&]{res = m_androidInputContext->getCursorCapsMode(reqModes);});
return res;
}
@@ -270,7 +269,7 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SET" << str << newCursorPosition;
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->setComposingText(str, newCursorPosition);});
return res;
}
@@ -283,7 +282,7 @@ static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SETR" << start << end;
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->setComposingRegion(start, end);});
return res;
}
@@ -297,7 +296,7 @@ static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SETSEL" << start << end;
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->setSelection(start, end);});
return res;
@@ -311,7 +310,7 @@ static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ SELALL");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->selectAll();});
return res;
}
@@ -324,7 +323,7 @@ static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->cut();});
return res;
}
@@ -337,7 +336,7 @@ static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->copy();});
return res;
}
@@ -350,7 +349,7 @@ static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->copyURL();});
return res;
}
@@ -363,7 +362,7 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ PASTE");
#endif
- jboolean res;
+ jboolean res = JNI_FALSE;
runOnQtThread([&]{res = m_androidInputContext->paste();});
return res;
}
@@ -516,7 +515,6 @@ QAndroidInputContext::QAndroidInputContext()
m_handleMode = Hidden;
updateSelectionHandles();
});
- qRegisterMetaType<std::function<void()>>();
}
QAndroidInputContext::~QAndroidInputContext()
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
index 763a4a462b..2fc076ad0c 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
@@ -65,7 +65,7 @@ void QEglFSVivIntegration::platformInit()
VivanteInit();
mNativeDisplay = fbGetDisplay();
#else
- mNativeDisplay = fbGetDisplayByIndex(framebufferIndex());
+ mNativeDisplay = static_cast<EGLNativeDisplayType>(fbGetDisplayByIndex(framebufferIndex()));
#endif
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
@@ -88,7 +88,7 @@ EGLNativeWindowType QEglFSVivIntegration::createNativeWindow(QPlatformWindow *wi
Q_UNUSED(window)
Q_UNUSED(format)
- EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height());
+ EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()));
return eglWindow;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp
index 61e2f17766..3bdae239cd 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp
@@ -60,7 +60,7 @@ void QEglFSVivWaylandIntegration::platformInit()
}
mWaylandDisplay = wl_display_create();
- mNativeDisplay = fbGetDisplay(mWaylandDisplay);
+ mNativeDisplay = static_cast<EGLNativeDisplayType>(fbGetDisplay(mWaylandDisplay));
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
mScreenSize.setHeight(height);
mScreenSize.setWidth(width);
@@ -81,7 +81,7 @@ EGLNativeWindowType QEglFSVivWaylandIntegration::createNativeWindow(QPlatformWin
Q_UNUSED(window)
Q_UNUSED(format)
- EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height());
+ EGLNativeWindowType eglWindow = static_cast<EGLNativeWindowType>(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()));
return eglWindow;
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
index 7935d0c36f..e428a8cf63 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp
@@ -54,7 +54,6 @@
# include "qwindowsdrag.h"
#endif
-#include <qpa/qwindowsysteminterface.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qscreen.h>
#include <QtGui/qtouchdevice.h>
@@ -201,6 +200,8 @@ 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;
@@ -427,6 +428,15 @@ 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);
@@ -455,6 +465,103 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice()
return m_touchDevice;
}
+void QWindowsPointerHandler::handleCaptureRelease(QWindow *window,
+ QWindow *currentWindowUnderPointer,
+ HWND hwnd,
+ QEvent::Type eventType,
+ Qt::MouseButtons mouseButtons)
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+
+ // Qt expects the platform plugin to capture the mouse on any button press until release.
+ if (!platformWindow->hasMouseCapture() && eventType == QEvent::MouseButtonPress) {
+
+ platformWindow->setMouseGrabEnabled(true);
+ platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
+ qCDebug(lcQpaEvents) << "Automatic mouse capture " << window;
+
+ // 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();
+
+ } else if (platformWindow->hasMouseCapture()
+ && platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)
+ && eventType == QEvent::MouseButtonRelease
+ && !mouseButtons) {
+
+ platformWindow->setMouseGrabEnabled(false);
+ qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window;
+ }
+
+ // Enter new window: track to generate leave event.
+ // If there is an active capture, only track if the current window is capturing,
+ // so we don't get extra leave when cursor leaves the application.
+ if (window != m_currentWindow &&
+ (!platformWindow->hasMouseCapture() || currentWindowUnderPointer == window)) {
+ trackLeave(hwnd);
+ m_currentWindow = window;
+ }
+}
+
+void QWindowsPointerHandler::handleEnterLeave(QWindow *window,
+ QWindow *currentWindowUnderPointer,
+ QPoint globalPos)
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+ const bool hasCapture = platformWindow->hasMouseCapture();
+
+ // No enter or leave events are sent as long as there is an autocapturing window.
+ if (!hasCapture || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) {
+
+ // Leave is needed if:
+ // 1) There is no capture and we move from a window to another window.
+ // Note: Leaving the application entirely is handled in translateMouseEvent(WM_MOUSELEAVE).
+ // 2) There is capture and we move out of the capturing window.
+ // 3) There is a new capture and we were over another window.
+ if ((m_windowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer
+ && (!hasCapture || window == m_windowUnderPointer))
+ || (hasCapture && m_previousCaptureWindow != window && m_windowUnderPointer
+ && m_windowUnderPointer != window)) {
+
+ qCDebug(lcQpaEvents) << "Leaving window " << m_windowUnderPointer;
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
+
+ if (hasCapture && currentWindowUnderPointer != window) {
+ // Clear tracking if capturing and current window is not the capturing window
+ // to avoid leave when mouse actually leaves the application.
+ m_currentWindow = nullptr;
+ // We are not officially in any window, but we need to set some cursor to clear
+ // whatever cursor the left window had, so apply the cursor of the capture window.
+ platformWindow->applyCursor();
+ }
+ }
+
+ // Enter is needed if:
+ // 1) There is no capture and we move to a new window.
+ // 2) There is capture and we move into the capturing window.
+ // 3) The capture just ended and we are over non-capturing window.
+ if ((currentWindowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer
+ && (!hasCapture || currentWindowUnderPointer == window))
+ || (m_previousCaptureWindow && !hasCapture && currentWindowUnderPointer
+ && currentWindowUnderPointer != m_previousCaptureWindow)) {
+
+ QPoint wumLocalPos;
+ if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer)) {
+ wumLocalPos = wumPlatformWindow->mapFromGlobal(globalPos);
+ wumPlatformWindow->applyCursor();
+ }
+ qCDebug(lcQpaEvents) << "Entering window " << currentWindowUnderPointer;
+ QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, wumLocalPos, globalPos);
+ }
+
+ // We need to track m_windowUnderPointer separately from m_currentWindow, as Windows
+ // mouse tracking will not trigger WM_MOUSELEAVE for leaving window when mouse capture is set.
+ m_windowUnderPointer = currentWindowUnderPointer;
+ }
+
+ m_previousCaptureWindow = hasCapture ? window : nullptr;
+}
+
bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd,
QtWindows::WindowsEventType et,
MSG msg, PVOID vPointerInfo)
@@ -464,9 +571,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h
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);
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
switch (msg.message) {
case WM_NCPOINTERDOWN:
@@ -485,38 +590,17 @@ 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);
- m_currentWindow = nullptr;
- }
-
- if (currentWindowUnderPointer) {
- if (currentWindowUnderPointer != m_currentWindow) {
- QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
- m_currentWindow = currentWindowUnderPointer;
- if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
- wumPlatformWindow->applyCursor();
- trackLeave(hwnd);
- }
- } else {
- platformWindow->applyCursor();
- }
- m_windowUnderPointer = currentWindowUnderPointer;
- }
+
+ 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 mouse is captured, as it would mess with menu processing.
- return msg.message != WM_POINTERDOWN || GetCapture();
+ // unless the click was on a menu, as it would mess with menu processing.
+ return msg.message != WM_POINTERDOWN || isMenuWindow(window);
}
}
case WM_POINTERHWHEEL:
@@ -641,6 +725,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
// 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());
}
@@ -755,6 +840,16 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
#endif
}
+static inline bool isMouseEventSynthesizedFromPenOrTouch()
+{
+ // For details, see
+ // https://docs.microsoft.com/en-us/windows/desktop/tablet/system-events-and-mouse-messages
+ const LONG_PTR SIGNATURE_MASK = 0xFFFFFF00;
+ const LONG_PTR MI_WP_SIGNATURE = 0xFF515700;
+
+ 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)
{
@@ -763,8 +858,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
flushTabletEvents();
*result = 0;
- if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE)
- return false;
const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam));
QPoint localPos;
@@ -778,7 +871,26 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle());
+ const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
+
+ // 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) {
@@ -799,50 +911,21 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW
}
if (msg.message == WM_MOUSELEAVE) {
+
if (window == m_currentWindow) {
- QWindowSystemInterface::handleLeaveEvent(window);
+ QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow;
+ qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget;
+ QWindowSystemInterface::handleLeaveEvent(leaveTarget);
m_windowUnderPointer = nullptr;
m_currentWindow = nullptr;
- platformWindow->applyCursor();
}
- return false;
- }
-
- // 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.
- static QPoint lastMouseMovePos;
- const bool discardEvent = msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos);
- lastMouseMovePos = globalPos;
-
- QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
- if (currentWindowUnderPointer != m_windowUnderPointer) {
- if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) {
- QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer);
- m_currentWindow = nullptr;
- }
+ } else if (msg.message == WM_MOUSEMOVE) {
- if (currentWindowUnderPointer) {
- if (currentWindowUnderPointer != m_currentWindow) {
- QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos);
- m_currentWindow = currentWindowUnderPointer;
- if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer))
- wumPlatformWindow->applyCursor();
- trackLeave(hwnd);
- }
- } else {
- platformWindow->applyCursor();
- }
- m_windowUnderPointer = currentWindowUnderPointer;
+ QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
+ handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons);
+ handleEnterLeave(window, currentWindowUnderPointer, globalPos);
}
-
- const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam);
-
- if (!discardEvent)
- QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove,
- keyModifiers, Qt::MouseEventNotSynthesized);
return false;
}
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h
index 3861ebf919..ec3179e821 100644
--- a/src/plugins/platforms/windows/qwindowspointerhandler.h
+++ b/src/plugins/platforms/windows/qwindowspointerhandler.h
@@ -46,6 +46,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qhash.h>
+#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
@@ -68,12 +69,16 @@ 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);
+ 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;
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/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index c69912c361..af72285135 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -287,7 +287,7 @@ void QXcbBasicConnection::initializeShm()
logging->setEnabled(QtMsgType::QtWarningMsg, true);
}
-void QXcbBasicConnection::initializeXRandr()
+void QXcbBasicConnection::initializeXRender()
{
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id);
if (!reply || !reply->present) {
@@ -303,7 +303,7 @@ void QXcbBasicConnection::initializeXRandr()
return;
}
- m_hasXRandr = true;
+ m_hasXRender = true;
m_xrenderVersion.first = xrenderQuery->major_version;
m_xrenderVersion.second = xrenderQuery->minor_version;
}
@@ -337,7 +337,7 @@ void QXcbBasicConnection::initializeXFixes()
m_xfixesFirstEvent = reply->first_event;
}
-void QXcbBasicConnection::initializeXRender()
+void QXcbBasicConnection::initializeXRandr()
{
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_randr_id);
if (!reply || !reply->present)
@@ -352,7 +352,7 @@ void QXcbBasicConnection::initializeXRender()
return;
}
- m_hasXRender = true;
+ m_hasXRandr = true;
m_xrandrFirstEvent = reply->first_event;
}
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 647058167b..db3d6629b3 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -112,4 +112,8 @@ qtConfig(xkb) {
qtConfig(dlopen): QMAKE_USE += libdl
+# qxcbkeyboard.cpp's KeyTbl has more than 256 levels of expansion and older
+# Clang uses that as a limit (it's 1024 in current versions).
+clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024
+
load(qt_module)