diff --git a/src/core/lockscreen.cpp b/src/core/lockscreen.cpp index ef14c2878..bf51df066 100644 --- a/src/core/lockscreen.cpp +++ b/src/core/lockscreen.cpp @@ -16,7 +16,6 @@ #include "rootsurfacecontainer.h" #include "surfacewrapper.h" -#include #include #include #endif @@ -37,12 +36,13 @@ LockScreen::LockScreen(ILockScreen *impl, SurfaceContainer *parent, GreeterProxy // The global login view is lazily created when this container becomes // visible (locked) and destroyed when it hides (unlocked). Track the - // cursor so the login UI follows the output the mouse is on. + // output under the cursor so the login UI follows the mouse without + // recomputing the output on every cursor motion. connect(this, &QQuickItem::visibleChanged, this, &LockScreen::onLoginViewVisibleChanged); - connect(rootContainer()->cursor(), - &WCursor::positionChanged, + connect(rootContainer(), + &RootSurfaceContainer::cursorOutputChanged, this, - &LockScreen::onCursorPositionChanged); + &LockScreen::repositionLoginView); } void LockScreen::lock() @@ -243,13 +243,6 @@ void LockScreen::repositionLoginView() m_loginView->setWidth(size.width()); m_loginView->setHeight(size.height()); } - -void LockScreen::onCursorPositionChanged() -{ - if (m_loginView) { - repositionLoginView(); - } -} #if EXT_SESSION_LOCK_V1 // ext_session_lock_v1 capabilities diff --git a/src/core/lockscreen.h b/src/core/lockscreen.h index dad4e3c98..ef07d69b9 100644 --- a/src/core/lockscreen.h +++ b/src/core/lockscreen.h @@ -80,7 +80,6 @@ private Q_SLOTS: void createLoginView(); void destroyLoginView(); void repositionLoginView(); - void onCursorPositionChanged(); Output *followerOutput() const; ILockScreen *m_impl{ nullptr }; diff --git a/src/core/rootsurfacecontainer.cpp b/src/core/rootsurfacecontainer.cpp index 61851d025..12a17a96b 100644 --- a/src/core/rootsurfacecontainer.cpp +++ b/src/core/rootsurfacecontainer.cpp @@ -86,6 +86,9 @@ void RootSurfaceContainer::init(WServer *server) output->updatePositionFromLayout(); } ensureCursorVisible(); + // The layout may have moved/removed the output under the cursor, so + // refresh the cache even without a cursor motion event. + updateCursorOutput(); // for (auto s : m_surfaceContainer->surfaces()) { // ensureSurfaceNormalPositionValid(s); @@ -101,6 +104,7 @@ void RootSurfaceContainer::init(WServer *server) QObject::connect(m_cursor, &WCursor::positionChanged, this, [this] { m_dragSurfaceItem->setPosition(m_cursor->position()); + updateCursorOutput(); }); QObject::connect(m_cursor, &WCursor::requestedDragSurfaceChanged, this, [this] { @@ -387,7 +391,17 @@ WCursor *RootSurfaceContainer::cursor() const Output *RootSurfaceContainer::cursorOutput() const { Q_ASSERT(m_cursor->layout() == m_outputLayout); - return outputAt(m_cursor->position()); + return m_cursorOutput; +} + +void RootSurfaceContainer::updateCursorOutput() +{ + Output *output = outputAt(m_cursor->position()); + if (output == m_cursorOutput) + return; + + m_cursorOutput = output; + Q_EMIT cursorOutputChanged(output); } Output *RootSurfaceContainer::outputAt(const QPointF &pos) const diff --git a/src/core/rootsurfacecontainer.h b/src/core/rootsurfacecontainer.h index 7091e73ed..f006542e3 100644 --- a/src/core/rootsurfacecontainer.h +++ b/src/core/rootsurfacecontainer.h @@ -121,6 +121,7 @@ public Q_SLOTS: Q_SIGNALS: void primaryOutputChanged(); + void cursorOutputChanged(Output *output); void moveResizeFinised(SurfaceWrapper *surface); private: @@ -138,6 +139,7 @@ public Q_SLOTS: [[maybe_unused]] SurfaceWrapper::State oldState) override; void ensureCursorVisible(); + void updateCursorOutput(); void updateSurfaceOutputs(SurfaceWrapper *surface); QQuickItem *ensureEdgeTilePreview(); void onSeatAdded(WSeat *seat); @@ -150,6 +152,7 @@ public Q_SLOTS: std::unique_ptr m_outputLayoutListenerOwner; OutputListModel *m_outputModel = nullptr; QPointer m_primaryOutput; + QPointer m_cursorOutput; WCursor *m_cursor = nullptr; WSurfaceItem *m_dragSurfaceItem = nullptr; QPointer m_edgeTilePreview;