diff --git a/src/private/DragController.cpp b/src/private/DragController.cpp index a9ba0186..01f39c0f 100644 --- a/src/private/DragController.cpp +++ b/src/private/DragController.cpp @@ -132,7 +132,11 @@ State *MinimalStateMachine::currentState() const void MinimalStateMachine::setCurrentState(State *state) { if (state != m_currentState) { + if (m_currentState) + m_currentState->onExit(); + m_currentState = state; + if (state) state->onEntry(); } @@ -238,12 +242,28 @@ bool StatePreDrag::handleMouseDoubleClick() StateDragging::StateDragging(DragController *parent) : StateBase(parent) { +#if defined(Q_OS_WIN) + m_maybeCancelDrag.setInterval(100); + QObject::connect(&m_maybeCancelDrag, &QTimer::timeout, this, [this] { + // Workaround bug #166 , where Qt doesn't agree with Window's mouse button state. + // Looking in the Qt bug tracker there's many hits, so do a quick workaround here: + + const bool mouseButtonIsReallyDown = (GetKeyState(VK_LBUTTON) & 0x8000); + if (!mouseButtonIsReallyDown && isLeftButtonPressed()) { + qCDebug(state) << "Canceling drag, Qt thinks mouse button is pressed" + << "but Windows knows it's not"; + Q_EMIT q->dragCanceled(); + } + }); +#endif } StateDragging::~StateDragging() = default; void StateDragging::onEntry() { + m_maybeCancelDrag.start(); + if (DockWidgetBase *dw = q->m_draggable->singleDockWidget()) { // When we start to drag a floating window which has a single dock widget, we save the position if (dw->isFloating()) @@ -296,6 +316,11 @@ void StateDragging::onEntry() } } +void StateDragging::onExit() +{ + m_maybeCancelDrag.stop(); +} + bool StateDragging::handleMouseButtonRelease(QPoint globalPos) { qCDebug(state) << "StateDragging: handleMouseButtonRelease"; @@ -345,7 +370,6 @@ bool StateDragging::handleMouseMove(QPoint globalPos) if (!q->m_nonClientDrag) fw->windowHandle()->setPosition(globalPos - q->m_offset); - if (fw->anyNonDockable()) { qCDebug(state) << "StateDragging: Ignoring non dockable floating window"; return true; diff --git a/src/private/DragController_p.h b/src/private/DragController_p.h index 2d81fc5d..fa7cf7d5 100644 --- a/src/private/DragController_p.h +++ b/src/private/DragController_p.h @@ -19,6 +19,7 @@ #include #include +#include #include @@ -42,6 +43,7 @@ public: bool isCurrentState() const; virtual void onEntry() = 0; + virtual void onExit() {}; private: MinimalStateMachine *const m_machine; }; @@ -180,9 +182,12 @@ public: explicit StateDragging(DragController *parent); ~StateDragging() override; void onEntry() override; + void onExit() override; bool handleMouseButtonRelease(QPoint globalPos) override; bool handleMouseMove(QPoint globalPos) override; bool handleMouseDoubleClick() override; +private: + QTimer m_maybeCancelDrag; }; // Used on wayland only to use QDrag instead of setting geometry on mouse-move.