From d47466e4fb23a55487ae7425b3e3c4e9439d8f6b Mon Sep 17 00:00:00 2001 From: zhaoyingzhen Date: Tue, 9 Jun 2026 19:59:16 +0800 Subject: [PATCH] fix: route screen lock through logind on Wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Wayland the lock screen is provided by treeland (driven by the logind Lock signal), but RequestLock() unconditionally called the X11-only org.deepin.dde.LockFront1 (dde-lock). Under Wayland dde-lock.service is ExecCondition-disabled, so that D-Bus name has no provider and the call hangs on the 120s activation timeout, logging "failed to lock". A Wayland guard used to exist on this path and was dropped during an earlier refactor. Gate the lock path on Utils::IS_WAYLAND_DISPLAY: - RequestLock() asks logind to Lock() so treeland shows the lock screen. - handleLoginSessionLocked() only syncs local lock state (treeland reacts to the same logind signal; re-entering RequestLock would loop). - handleLoginSessionUnlocked() only syncs state, skipping the X11 LockFront1-kill dance that early-returns and leaves m_locked stale. 在 Wayland 下锁屏由 treeland 提供(响应 logind 的 Lock 信号),但 RequestLock() 无条件调用了仅 X11 有效的 org.deepin.dde.LockFront1(dde-lock)。Wayland 下 dde-lock.service 被 ExecCondition 禁用,该 D-Bus 名无人提供,调用会卡在 120s 的 激活超时并打印 "failed to lock"。此路径原有的 Wayland 判断在之前的重构中被丢失。 按 Utils::IS_WAYLAND_DISPLAY 分流: - RequestLock() 改为请求 logind Lock(),由 treeland 显示锁屏; - handleLoginSessionLocked() 仅同步本地锁状态(treeland 已响应同一 logind 信号, 再次进入 RequestLock 会形成回环); - handleLoginSessionUnlocked() 仅同步状态,跳过会提前 return 并使 m_locked 不一致 的 X11 LockFront1 kill 流程。 Log: route screen lock through logind on Wayland Change-Id: Iab1b9648ec8f53eca3023891ac33cc76d7f8f59b --- src/dde-session/impl/sessionmanager.cpp | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/dde-session/impl/sessionmanager.cpp b/src/dde-session/impl/sessionmanager.cpp index a0b3edc..dea3735 100644 --- a/src/dde-session/impl/sessionmanager.cpp +++ b/src/dde-session/impl/sessionmanager.cpp @@ -426,6 +426,16 @@ void SessionManager::RequestHibernate() void SessionManager::RequestLock() { + if (Utils::IS_WAYLAND_DISPLAY) { + // On Wayland the lock screen is owned by treeland and driven via logind. + // The X11-only LockFront1 (dde-lock) has no provider here, so calling it + // would hang on a 120s D-Bus activation timeout. Ask logind to lock. + qDebug() << "RequestLock on wayland: ask logind to lock"; + m_login1SessionInter->Lock(); + m_inCallRequestLock = false; + return; + } + QDBusInterface inter("org.deepin.dde.LockFront1", "/org/deepin/dde/LockFront1", "org.deepin.dde.LockFront1", QDBusConnection::sessionBus()); // 使用异步调用方式防止当前线程阻塞 @@ -1025,6 +1035,15 @@ void SessionManager::handleLoginSessionLocked() return; } + if (Utils::IS_WAYLAND_DISPLAY) { + // On Wayland treeland shows the lock screen on this same logind Lock + // signal; only sync local state here (calling RequestLock would loop). + qDebug() << "handleLoginSessionLocked on wayland: sync local state"; + m_locked = true; + emitLockChanged(true); + return; + } + // 防止短时间内多次同时调用 RequestLock if (m_inCallRequestLock) { qDebug() << "handleLoginSessionLocked inCall is true, return"; @@ -1041,6 +1060,15 @@ void SessionManager::handleLoginSessionUnlocked() { qDebug() << "login session unlocked."; + if (Utils::IS_WAYLAND_DISPLAY) { + // On Wayland there is no X11 LockFront1 process to kill; only sync state. + qDebug() << "handleLoginSessionUnlocked on wayland: sync local state"; + m_locked = false; + emitLockChanged(false); + Q_EMIT Unlock(); + return; + } + bool sessionActive = m_login1SessionInter->active(); if (sessionActive) { Q_EMIT Unlock();