Windows QPA: Fix release button event type after moving windows

Check whether the mouse is inside the window and report
MouseButtonRelease or QEvent::NonClientAreaMouseButtonRelease,
respectively. The inside case is triggered by programmatically
starting a size move via QPlatformWindow::startSystemResize()
(QSizeGrip) and was overlooked in
7c3ecf85a7.

Complements 4589440891,
7c3ecf85a7.

Change-Id: I8f714dc768a163878c2b4a075470bcee2dfbd802
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Reviewed-by: Andre de la Rocha <andre.rocha@qt.io>
This commit is contained in:
Friedemann Kleint 2018-05-30 10:27:03 +02:00
parent b9935239db
commit 3d841556bf

View File

@ -180,24 +180,31 @@ Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
void QWindowsMouseHandler::handleExitSizeMove(QWindow *window)
{
// When moving a window by dragging the title bar, no WM_NCLBUTTONUP is
// received after WM_NCLBUTTONDOWN, WM_NCMOUSEMOVE (due to internal
// mouse capture), which can leave the left mouse button 'pressed'
// in QGuiApplication's state. Intercept WM_EXITSIZEMOVE to sync the buttons.
// Windows can be moved/resized by:
// 1) User moving a window by dragging the title bar: Causes a sequence
// of WM_NCLBUTTONDOWN, WM_NCMOUSEMOVE but no WM_NCLBUTTONUP,
// leaving the left mouse button 'pressed'
// 2) User choosing Resize/Move from System menu and using mouse/cursor keys:
// No mouse events are received
// 3) Programmatically via QSizeGrip calling QPlatformWindow::startSystemResize/Move():
// Mouse is left in pressed state after press on size grip (inside window),
// no further mouse events are received
// For cases 1,3, intercept WM_EXITSIZEMOVE to sync the buttons.
const Qt::MouseButtons currentButtons = QWindowsMouseHandler::queryMouseButtons();
const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
if (currentButtons == appButtons)
return;
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const QPoint globalPos = QWindowsCursor::mousePosition();
const QPoint localPos = window->handle()->mapFromGlobal(globalPos);
const QPlatformWindow *platWin = window->handle();
const QPoint localPos = platWin->mapFromGlobal(globalPos);
const QEvent::Type type = platWin->geometry().contains(globalPos)
? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
currentButtons, button,
QEvent::NonClientAreaMouseButtonRelease,
keyboardModifiers,
Qt::MouseEventNotSynthesized);
currentButtons, button, type,
keyboardModifiers);
}
}
}