diff --git a/src/core/rootsurfacecontainer.h b/src/core/rootsurfacecontainer.h index 79cc7c5a9..244c3a5bf 100644 --- a/src/core/rootsurfacecontainer.h +++ b/src/core/rootsurfacecontainer.h @@ -64,6 +64,7 @@ class RootSurfaceContainer : public SurfaceContainer void destroyForSurface(SurfaceWrapper *wrapper); SeatSurfaceManager *getSeatContainer(WSeat *seat) const; + const QMap &seatContainers() const { return m_seatContainers; } WSeat *getDefaultSeat() const; SeatSurfaceManager *getSeatContainerOrDefault(WSeat *seat = nullptr) const; diff --git a/src/seat/helper.cpp b/src/seat/helper.cpp index 80291148e..988927f7c 100644 --- a/src/seat/helper.cpp +++ b/src/seat/helper.cpp @@ -1832,6 +1832,21 @@ void Helper::fakePressSurfaceBottomRightToReszie(SurfaceWrapper *surface) Q_EMIT surface->resizeRequested(Qt::BottomEdge | Qt::RightEdge); } +bool Helper::beforeHandleEvent(WSeat *seat, WSurface *watched, QObject *, + QObject *, QInputEvent *event) +{ + auto eventType = event->type(); + if (eventType != QEvent::MouseMove && eventType != QEvent::HoverMove) + return false; + + auto *container = m_rootSurfaceContainer->getSeatContainer(seat); + if (container && container->moveResizeState().surface + && container->moveResizeState().surface->surface() == watched) + return true; + + return false; +} + bool Helper::beforeDisposeEvent(WSeat *seat, QWindow *targetWindow, QInputEvent *event) { if (!m_instance || !m_renderWindow || !m_backend) { @@ -1957,10 +1972,12 @@ bool Helper::beforeDisposeEvent(WSeat *seat, QWindow *targetWindow, QInputEvent // Per-seat move/resize handling const auto *seatContainer = m_rootSurfaceContainer->getSeatContainer(seat); if (seatContainer && seatContainer->moveResizeState().surface) { - if (Q_LIKELY(event->type() == QEvent::MouseMove || event->type() == QEvent::TouchUpdate)) { + if (Q_LIKELY(event->type() == QEvent::MouseMove + || event->type() == QEvent::HoverMove + || event->type() == QEvent::TouchUpdate)) { auto cursor = seat->cursor(); Q_ASSERT(cursor); - QMouseEvent *ev = static_cast(event); + auto *ev = static_cast(event); const auto &moveResizeState = seatContainer->moveResizeState(); auto ownsOutput = moveResizeState.surface->ownsOutput(); diff --git a/src/seat/helper.h b/src/seat/helper.h index b9cd38ece..23362c755 100644 --- a/src/seat/helper.h +++ b/src/seat/helper.h @@ -334,6 +334,8 @@ private Q_SLOTS: void setCursorPosition(const QPointF &position); bool beforeDisposeEvent(WSeat *seat, QWindow *window, QInputEvent *event) override; + bool beforeHandleEvent(WSeat *seat, WSurface *watched, QObject *shellObject, + QObject *eventObject, QInputEvent *event) override; bool afterHandleEvent(WSeat *seat, WSurface *watched, QObject *shellObject, QObject *eventObject, QInputEvent *event) override; bool unacceptedEvent(WSeat *seat, QWindow *window, QInputEvent *event) override; diff --git a/src/surface/seatsurfacemanager.cpp b/src/surface/seatsurfacemanager.cpp index 05249ae78..94ffb8055 100644 --- a/src/surface/seatsurfacemanager.cpp +++ b/src/surface/seatsurfacemanager.cpp @@ -94,6 +94,13 @@ void SeatSurfaceManager::setKeyboardFocusSurface(SurfaceWrapper *surface) void SeatSurfaceManager::beginMoveResize(SurfaceWrapper *surface, Qt::Edges edges) { + // Guard against re-entry: beginMoveResizeForSeat() may invoke this again + // with the same surface+edges. Without this early return, the subsequent + // endMoveResize() call would briefly clear the state, causing the + // surface to lose its move/resize tracking. + if (m_moveResizeState.surface == surface && m_moveResizeState.edges == edges) + return; + if (m_moveResizeState.surface) endMoveResize();