Windows QPA: Fix left button reported pressed after moving windows

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.

Complements 4589440891.

Change-Id: I94d18d1d4a4796dcecb1a9731809d05c7f9ddd65
Reviewed-by: Andre de la Rocha <andre.rocha@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
bb10
Friedemann Kleint 2018-05-03 11:03:16 +02:00
parent 811db6262f
commit 7c3ecf85a7
3 changed files with 27 additions and 0 deletions

View File

@ -1093,6 +1093,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::ExitSizeMoveEvent:
platformWindow->clearFlag(QWindowsWindow::ResizeMoveActive);
platformWindow->checkForScreenChanged();
QWindowsMouseHandler::handleExitSizeMove(platformWindow->window());
return true;
case QtWindows::ScrollEvent:
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);

View File

@ -178,6 +178,30 @@ Qt::MouseButtons QWindowsMouseHandler::queryMouseButtons()
return result;
}
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.
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);
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);
}
}
}
static QPoint lastMouseMovePos;
namespace {

View File

@ -80,6 +80,8 @@ public:
QWindow *windowUnderMouse() const { return m_windowUnderMouse.data(); }
void clearWindowUnderMouse() { m_windowUnderMouse = 0; }
static void handleExitSizeMove(QWindow *window);
private:
inline bool translateMouseWheelEvent(QWindow *window, HWND hwnd,
MSG msg, LRESULT *result);