summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowsmousehandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsmousehandler.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp79
1 files changed, 48 insertions, 31 deletions
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 2f624c3e16..2f2d5d2c59 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -130,7 +130,8 @@ QWindowsMouseHandler::QWindowsMouseHandler() :
m_windowUnderMouse(0),
m_trackedWindow(0),
m_touchDevice(0),
- m_leftButtonDown(false)
+ m_leftButtonDown(false),
+ m_previousCaptureWindow(0)
{
}
@@ -212,6 +213,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (QWindowsContext::verboseEvents)
qDebug() << "Automatic mouse capture for missing buttondown event" << window;
}
+ m_previousCaptureWindow = window;
return true;
} else if (m_leftButtonDown && !actualLeftDown) {
m_leftButtonDown = false;
@@ -253,12 +255,13 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
}
+ const bool hasCapture = platformWindow->hasMouseCapture();
+ const bool currentNotCapturing = hasCapture && currentWindowUnderMouse != window;
#ifndef Q_OS_WINCE
// Enter new window: track to generate leave event.
- // If there is an active capture, we must track the actual capture window instead of window
- // under cursor or leaves will trigger constantly, so always track the window we got
- // native mouse event for.
- if (window != m_trackedWindow) {
+ // 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_trackedWindow && !currentNotCapturing) {
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
@@ -270,39 +273,53 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
#endif // !Q_OS_WINCE
- // Qt expects enter/leave events for windows even when some window is capturing mouse input,
- // except for automatic capture when mouse button is pressed - in that case enter/leave
- // should be sent only after the last button is released.
- // We need to track m_windowUnderMouse separately from m_trackedWindow, as
- // Windows mouse tracking will not trigger WM_MOUSELEAVE for leaving window when
- // mouse capture is set.
- if (!platformWindow->hasMouseCapture()
- || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) {
- if (m_windowUnderMouse != currentWindowUnderMouse) {
- if (m_windowUnderMouse) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Synthetic leave for " << m_windowUnderMouse;
- QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
- // Clear tracking if we are no longer over application,
- // since we have already sent the leave.
- if (!currentWindowUnderMouse)
- m_trackedWindow = 0;
- }
-
- if (currentWindowUnderMouse) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Entering " << currentWindowUnderMouse;
- QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
- QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse,
- currentWindowUnderMouse->mapFromGlobal(globalPosition),
- globalPosition);
+ // 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 WM_MOUSELEAVE case.
+ // 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_windowUnderMouse && m_windowUnderMouse != currentWindowUnderMouse
+ && (!hasCapture || window == m_windowUnderMouse))
+ || (hasCapture && m_previousCaptureWindow != window && m_windowUnderMouse
+ && m_windowUnderMouse != window)) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
+ if (currentNotCapturing) {
+ // Clear tracking if capturing and current window is not the capturing window
+ // to avoid leave when mouse actually leaves the application.
+ m_trackedWindow = 0;
+ // 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.
+ QWindowsWindow::baseWindowOf(window)->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 ((currentWindowUnderMouse && m_windowUnderMouse != currentWindowUnderMouse
+ && (!hasCapture || currentWindowUnderMouse == window))
+ || (m_previousCaptureWindow && window != m_previousCaptureWindow && currentWindowUnderMouse
+ && currentWindowUnderMouse != m_previousCaptureWindow)) {
+ if (QWindowsContext::verboseEvents)
+ qDebug() << "Entering " << currentWindowUnderMouse;
+ QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
+ QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse,
+ currentWindowUnderMouse->mapFromGlobal(globalPosition),
+ globalPosition);
+ }
+ // We need to track m_windowUnderMouse separately from m_trackedWindow, as
+ // Windows mouse tracking will not trigger WM_MOUSELEAVE for leaving window when
+ // mouse capture is set.
m_windowUnderMouse = currentWindowUnderMouse;
}
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
QWindowsKeyMapper::queryKeyboardModifiers());
+ m_previousCaptureWindow = hasCapture ? window : 0;
return true;
}