From b03e138714639858613b8843445b8da336a0093c Mon Sep 17 00:00:00 2001 From: liujiangtao1 Date: Mon, 14 Sep 2026 15:29:13 +0800 Subject: [PATCH 1/2] fix(lockscreen): fix login view disappearing after TTY switch and hotplug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use QPointer for m_loginView so it is automatically nulled when QML destroys the item, preventing dangling pointer access after TTY switches that disable and re-enable DRM outputs. Connect WOutput::enabledChanged in addOutput() to rebuild or reposition the login view when an output is re-enabled, and call repositionLoginView() so newly added outputs can be followed. Add rebuild logic in onCursorPositionChanged() and the new onOutputEnabledChanged() to recreate the login view when it has been destroyed by QML but the lock screen is still visible. 将 m_loginView 从裸指针改为 QPointer,QML 销毁后 自动置 null,避免 TTY 切换导致 DRM 输出禁用/启用时产生悬空指针。 addOutput 中连接 enabledChanged 信号并调用 repositionLoginView, 使热插拔副屏后登录界面可跟随鼠标。onCursorPositionChanged 和新增 的 onOutputEnabledChanged 在 m_loginView 为空且界面可见时重建。 Log: 修复TTY切回后登录界面消失及副屏热插拔后不跟随鼠标 Issue: Fixes WM-465 Influence: TTY切换回来后登录界面不再消失,副屏热插拔后登录/电源 界面正常跟随鼠标显示在对应屏幕上。 --- src/core/lockscreen.cpp | 34 ++++++++++++++++++++++++++++++++-- src/core/lockscreen.h | 3 ++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/core/lockscreen.cpp b/src/core/lockscreen.cpp index cfb75b0ff..42c9d55ba 100644 --- a/src/core/lockscreen.cpp +++ b/src/core/lockscreen.cpp @@ -12,6 +12,8 @@ #include +#include + #ifdef EXT_SESSION_LOCK_V1 #include "rootsurfacecontainer.h" #include "surfacewrapper.h" @@ -100,6 +102,11 @@ void LockScreen::addOutput(Output *output) SurfaceContainer::addOutput(output); auto outputItem = output->outputItem(); connect(outputItem, &WOutputItem::geometryChanged, this, &LockScreen::repositionLoginView); + connect(output->output(), + &WOutput::enabledChanged, + this, + &LockScreen::onOutputEnabledChanged, + Qt::UniqueConnection); #if EXT_SESSION_LOCK_V1 connect(outputItem, &WOutputItem::geometryChanged, this, &LockScreen::onOutputGeometryChanged); @@ -117,6 +124,8 @@ void LockScreen::addOutput(Output *output) { output, std::unique_ptr(item, [](QQuickItem *item) { item->deleteLater(); }) }); + + repositionLoginView(); } bool LockScreen::isLocked() const @@ -131,6 +140,7 @@ void LockScreen::removeOutput(Output *output) SurfaceContainer::removeOutput(output); auto outputItem = output->outputItem(); disconnect(outputItem, &WOutputItem::geometryChanged, this, &LockScreen::repositionLoginView); + disconnect(output->output(), &WOutput::enabledChanged, this, &LockScreen::onOutputEnabledChanged); #if EXT_SESSION_LOCK_V1 disconnect(outputItem, @@ -238,9 +248,29 @@ void LockScreen::repositionLoginView() void LockScreen::onCursorPositionChanged() { - if (m_loginView) { - repositionLoginView(); + if (!m_loginView) { + if (isVisible()) { + createLoginView(); + } + return; } + repositionLoginView(); +} + +void LockScreen::onOutputEnabledChanged() +{ + auto *woutput = qobject_cast(sender()); + if (!woutput || !woutput->isEnabled()) { + return; + } + + if (!m_loginView) { + if (isVisible()) { + createLoginView(); + } + return; + } + repositionLoginView(); } #if EXT_SESSION_LOCK_V1 // ext_session_lock_v1 capabilities diff --git a/src/core/lockscreen.h b/src/core/lockscreen.h index 458989b49..f8839b8ce 100644 --- a/src/core/lockscreen.h +++ b/src/core/lockscreen.h @@ -74,6 +74,7 @@ private Q_SLOTS: void createLoginView(); void destroyLoginView(); void repositionLoginView(); + void onOutputEnabledChanged(); void onCursorPositionChanged(); Output *followerOutput() const; @@ -86,5 +87,5 @@ private Q_SLOTS: std::map>> m_fallbackItems; WSessionLock* m_sessionLock{ nullptr }; #endif - QQuickItem *m_loginView{ nullptr }; + QPointer m_loginView; }; From bc95b8ec932ee44faffc5a95eed8240757eb1679 Mon Sep 17 00:00:00 2001 From: glyvut Date: Tue, 15 Sep 2026 20:13:35 +0800 Subject: [PATCH 2/2] fix(lockscreen): unconditional destroy+rebuild login view on output enabled onOutputEnabledChanged() previously guarded with if(!m_loginView), which prevented rebuilding when the QML scene graph survived the TTY switch. Now unconditionally destroyLoginView()+createLoginView() via QTimer::singleShot(0) to force a fresh QML component and restore rendering state. --- src/core/lockscreen.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/lockscreen.cpp b/src/core/lockscreen.cpp index 42c9d55ba..c6291ea29 100644 --- a/src/core/lockscreen.cpp +++ b/src/core/lockscreen.cpp @@ -14,6 +14,8 @@ #include +#include + #ifdef EXT_SESSION_LOCK_V1 #include "rootsurfacecontainer.h" #include "surfacewrapper.h" @@ -264,13 +266,14 @@ void LockScreen::onOutputEnabledChanged() return; } - if (!m_loginView) { - if (isVisible()) { - createLoginView(); - } + if (!isVisible()) { return; } - repositionLoginView(); + + QTimer::singleShot(0, this, [this]() { + destroyLoginView(); + createLoginView(); + }); } #if EXT_SESSION_LOCK_V1 // ext_session_lock_v1 capabilities