diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e3dc53f..2edaf497 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -182,10 +182,6 @@ elseif(NOT APPLE AND NOT EMSCRIPTEN AND NOT OPTION_QT6) target_link_libraries(kddockwidgets PUBLIC Qt${QT_MAJOR_VERSION}::X11Extras) endif() -#if (OPTION_QT6) -# target_link_libraries(kddockwidgets PUBLIC Qt6::StateMachine) -#endif() - set_target_properties(kddockwidgets PROPERTIES SOVERSION ${${PROJECT_NAME}_SOVERSION} VERSION ${${PROJECT_NAME}_VERSION} diff --git a/src/private/DragController.cpp b/src/private/DragController.cpp index 8b1ac052..3db28de6 100644 --- a/src/private/DragController.cpp +++ b/src/private/DragController.cpp @@ -94,8 +94,49 @@ FallbackMouseGrabber::~FallbackMouseGrabber() {} } +State::State(MinimalStateMachine *parent) + : QObject(parent) + , m_machine(parent) +{ +} + +bool State::isCurrentState() const +{ + return m_machine->currentState() == this; +} + +MinimalStateMachine::MinimalStateMachine(QObject *parent) + : QObject(parent) +{ +} + +template +void State::addTransition(Obj *obj, Signal signal, State *dest) +{ + connect(obj, signal, this, [this, dest] { + if (isCurrentState()) { + m_machine->setCurrentState(dest); + } + }); +} + + +State *MinimalStateMachine::currentState() const +{ + return m_currentState; +} + +void MinimalStateMachine::setCurrentState(State *state) +{ + if (state != m_currentState) { + m_currentState = state; + if (state) + state->onEntry(); + } +} + StateBase::StateBase(DragController *parent) - : QState(parent) + : State(parent) , q(parent) { } @@ -112,7 +153,7 @@ StateNone::StateNone(DragController *parent) { } -void StateNone::onEntry(QEvent *) +void StateNone::onEntry() { qCDebug(state) << "StateNone entered"; q->m_pressPos = QPoint(); @@ -153,7 +194,7 @@ StatePreDrag::StatePreDrag(DragController *parent) StatePreDrag::~StatePreDrag() = default; -void StatePreDrag::onEntry(QEvent *) +void StatePreDrag::onEntry() { qCDebug(state) << "StatePreDrag entered"; WidgetResizeHandler::s_disableAllHandlers = true; // Disable the resize handler during dragging @@ -190,7 +231,7 @@ StateDragging::StateDragging(DragController *parent) StateDragging::~StateDragging() = default; -void StateDragging::onEntry(QEvent *) +void StateDragging::onEntry() { 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 @@ -331,7 +372,7 @@ StateDraggingWayland::~StateDraggingWayland() { } -void StateDraggingWayland::onEntry(QEvent *) +void StateDraggingWayland::onEntry() { qCDebug(state) << "StateDragging entered"; @@ -415,7 +456,8 @@ bool StateDraggingWayland::handleDragMove(QDragMoveEvent *ev, DropArea *dropArea return true; } -DragController::DragController(QObject *) +DragController::DragController(QObject *parent) + : MinimalStateMachine(parent) { qCDebug(creation) << "DragController()"; @@ -433,8 +475,7 @@ DragController::DragController(QObject *) if (usesFallbackMouseGrabber()) enableFallbackMouseGrabber(); - setInitialState(stateNone); - start(); + setCurrentState(stateNone); } DragController *DragController::instance() @@ -517,7 +558,7 @@ bool DragController::eventFilter(QObject *o, QEvent *e) // On Windows, non-client mouse moves are only sent at the end, so we must fake it: qCDebug(mouseevents) << "DragController::eventFilter e=" << e->type() << "; o=" << o; activeState()->handleMouseMove(QCursor::pos()); - return QStateMachine::eventFilter(o, e); + return false; } if (isWayland()) { @@ -546,11 +587,11 @@ bool DragController::eventFilter(QObject *o, QEvent *e) QMouseEvent *me = mouseEvent(e); if (!me) - return QStateMachine::eventFilter(o, e); + return false; auto w = qobject_cast(o); if (!w) - return QStateMachine::eventFilter(o, e); + return false; qCDebug(mouseevents) << "DragController::eventFilter e=" << e->type() << "; o=" << o << "; m_nonClientDrag=" << m_nonClientDrag; @@ -563,7 +604,7 @@ bool DragController::eventFilter(QObject *o, QEvent *e) return activeState()->handleMouseButtonPress(draggableForQObject(o), Qt5Qt6Compat::eventGlobalPos(me), me->pos()); } } - return QStateMachine::eventFilter(o, e); + return false; } case QEvent::MouseButtonPress: // For top-level windows that support native dragging all goes through the NonClient* events. @@ -585,15 +626,12 @@ bool DragController::eventFilter(QObject *o, QEvent *e) break; } - return QStateMachine::eventFilter(o, e); + return false; } StateBase *DragController::activeState() const { - auto set = configuration(); - if (set.isEmpty()) - return nullptr; - return static_cast(*(set.begin())); + return static_cast(currentState()); } #if defined(Q_OS_WIN) diff --git a/src/private/DragController_p.h b/src/private/DragController_p.h index f0f205d1..efa3f008 100644 --- a/src/private/DragController_p.h +++ b/src/private/DragController_p.h @@ -17,7 +17,6 @@ #include "TitleBar_p.h" #include "WindowBeingDragged_p.h" -#include #include #include @@ -29,8 +28,36 @@ class StateBase; class DropArea; class Draggable; class FallbackMouseGrabber; +class MinimalStateMachine; -class DOCKS_EXPORT DragController : public QStateMachine +class State : public QObject +{ +public: + explicit State(MinimalStateMachine *parent); + + template + void addTransition(Obj *, Signal, State *dest); + bool isCurrentState() const; + + virtual void onEntry() = 0; +private: + MinimalStateMachine *const m_machine; +}; + +class MinimalStateMachine : public QObject +{ + Q_OBJECT +public: + explicit MinimalStateMachine(QObject *parent = nullptr); + + State *currentState() const; + void setCurrentState(State *); + +private: + State *m_currentState = nullptr; +}; + +class DOCKS_EXPORT DragController : public MinimalStateMachine { Q_OBJECT public: @@ -95,7 +122,7 @@ private: FallbackMouseGrabber *m_fallbackMouseGrabber = nullptr; }; -class StateBase : public QState +class StateBase : public State { Q_OBJECT public: @@ -126,7 +153,7 @@ class StateNone : public StateBase public: explicit StateNone(DragController *parent); ~StateNone() override; - void onEntry(QEvent *) override; + void onEntry() override; bool handleMouseButtonPress(Draggable *draggable, QPoint globalPos, QPoint pos) override; }; @@ -136,7 +163,7 @@ class StatePreDrag : public StateBase public: explicit StatePreDrag(DragController *parent); ~StatePreDrag() override; - void onEntry(QEvent *) override; + void onEntry() override; bool handleMouseMove(QPoint globalPos) override; bool handleMouseButtonRelease(QPoint) override; bool handleMouseDoubleClick() override; @@ -149,7 +176,7 @@ class StateDragging : public StateBase public: explicit StateDragging(DragController *parent); ~StateDragging() override; - void onEntry(QEvent *) override; + void onEntry() override; bool handleMouseButtonRelease(QPoint globalPos) override; bool handleMouseMove(QPoint globalPos) override; bool handleMouseDoubleClick() override; @@ -162,7 +189,7 @@ class StateDraggingWayland : public StateDragging public: explicit StateDraggingWayland(DragController *parent); ~StateDraggingWayland() override; - void onEntry(QEvent *) override; + void onEntry() override; bool handleMouseButtonRelease(QPoint globalPos) override; bool handleDragEnter(QDragEnterEvent *, DropArea *) override; bool handleDragMove(QDragMoveEvent *, DropArea *) override; diff --git a/src/private/indicators/AnimatedIndicators.cpp b/src/private/indicators/AnimatedIndicators.cpp index 19cc880b..774313d2 100644 --- a/src/private/indicators/AnimatedIndicators.cpp +++ b/src/private/indicators/AnimatedIndicators.cpp @@ -14,8 +14,6 @@ #include #include -#include -#include #define RUBBERBAND_LENGTH 11 #define RUBBERBAND_SPACING 2