qt6: Port away from QStateMachine

QStateMachine was moved to qtsxml module, which is not ported to
Qt6 yet.

We use QStateMachine for the semantics it gives us, not because of
its implementation. The implementation is trivial, so do it outselves.
We used very little from QStateMachine.
This commit is contained in:
Sergio Martins
2020-12-08 19:55:52 +00:00
parent 9f604829dd
commit f475312f11
4 changed files with 89 additions and 30 deletions

View File

@@ -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}

View File

@@ -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<typename Obj, typename Signal>
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<QWidgetOrQuick*>(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<StateBase *>(*(set.begin()));
return static_cast<StateBase *>(currentState());
}
#if defined(Q_OS_WIN)

View File

@@ -17,7 +17,6 @@
#include "TitleBar_p.h"
#include "WindowBeingDragged_p.h"
#include <QStateMachine>
#include <QPoint>
#include <QMimeData>
@@ -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 <typename Obj, typename Signal>
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;

View File

@@ -14,8 +14,6 @@
#include <QPainter>
#include <QPainterPath>
#include <QState>
#include <QStateMachine>
#define RUBBERBAND_LENGTH 11
#define RUBBERBAND_SPACING 2