Skip to content

feat(greeter): support undecided state waiting for DDM decision - #1305

Open
glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:greet
Open

feat(greeter): support undecided state waiting for DDM decision#1305
glyvut wants to merge 1 commit into
linuxdeepin:masterfrom
glyvut:greet

Conversation

@glyvut

@glyvut glyvut commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

前置:合入linuxdeepin/ddm#106

Add an undecided state so the greeter shows the wallpaper but keeps the login UI hidden until DDM decides between autologin and showing the greeter, with a 5s fallback timer.

为greeter增加undecided待决状态:先显示壁纸但隐藏登录界面,等待
DDM决定自动登录还是显示登录界面,并设置5秒兜底定时器防止停留在
壁纸。同时处理ShowGreeter消息和用户激活时的界面切换逻辑。

Log: 支持自动登录待决状态
Influence: 自动登录时不会闪现登录界面;DDM未决策时5秒后兜底显示登录界面。

Summary by Sourcery

Support deferred greeter decisions so autologin can proceed without briefly showing the login interface while retaining a timed fallback to the greeter.

New Features:

  • Add an undecided startup state that displays the wallpaper while deferring the login interface until DDM chooses autologin or greeter mode.
  • Support passwordless user login through a dedicated login action in the greeter UI.

Bug Fixes:

  • Prevent the greeter from remaining indefinitely on the wallpaper when DDM does not respond by falling back to the login screen after five seconds.
  • Ensure direct user activation hides the greeter even when normal session state notifications are unavailable.

Enhancements:

  • Handle DDM greeter-selection messages and expose undecided state changes to QML.
  • Improve user model handling for login sessions belonging to users not yet present in the model.

@deepin-ci-robot

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: glyvut

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduce an 'undecided' greeter state where the wallpaper/lockscreen surface is visible but the login UI is hidden until DDM decides to either autologin or show the full greeter, backed by a 5s fallback timer and updated lockscreen/greeter message handling.

Sequence diagram for undecided greeter state and decision flow

sequenceDiagram
    actor User
    participant DDM
    participant Helper
    participant GreeterProxy
    participant LockScreen
    participant QTimer

    Helper->>GreeterProxy: setLockScreenImpl(impl)
    Helper->>LockScreen: setVisible(true)
    GreeterProxy->>QTimer: m_undecidedTimer->start()
    Note over GreeterProxy,QTimer: m_undecided = true

    alt DDM decides to show greeter
        DDM->>GreeterProxy: readyRead() ShowGreeter
        GreeterProxy->>Helper: Helper::instance()->showLockScreen(false)
        Helper->>GreeterProxy: showLockScreen(false)
        GreeterProxy->>LockScreen: lock()
        GreeterProxy->>GreeterProxy: setLock(true)
        GreeterProxy->>GreeterProxy: m_undecided = false
        GreeterProxy->>GreeterProxy: undecidedChanged(false)
    else DDM decides to auto login
        DDM->>GreeterProxy: readyRead() UserActivateMessage
        GreeterProxy->>GreeterProxy: m_undecided = false
        GreeterProxy->>GreeterProxy: undecidedChanged(false)
        GreeterProxy->>LockScreen: m_lockScreen->unlock()
        GreeterProxy->>LockScreen: setVisible(false)
        GreeterProxy->>GreeterProxy: setLock(false)
    else DDM does not decide in time
        QTimer->>GreeterProxy: timeout
        GreeterProxy->>GreeterProxy: [m_undecided]
        GreeterProxy->>LockScreen: lock()
        GreeterProxy->>GreeterProxy: setLock(true)
        GreeterProxy->>GreeterProxy: m_undecided = false
        GreeterProxy->>GreeterProxy: undecidedChanged(false)
    end
Loading

File-Level Changes

Change Details Files
Add an undecided greeter state with a 5s fallback timer that controls when the login UI is shown or hidden based on DDM messages.
  • Expose a new Q_PROPERTY bool undecided on GreeterProxy with getter and undecidedChanged signal to represent the pre-decision state.
  • Initialize GreeterProxy with m_undecided=true and create a single-shot QTimer m_undecidedTimer (5s) that calls lock() if DDM has not decided in time.
  • Update Greeter.qml’s background state logic to keep the wallpaper surface visible when GreeterProxy.undecided is true, even if not locked.
src/greeter/greeterproxy.h
src/greeter/greeterproxy.cpp
src/plugins/lockscreen/qml/Greeter.qml
Adjust lockscreen startup and lock logic to support a visible-but-unlocked undecided state without breaking existing lock handling.
  • Remove the early return on isVisible() in LockScreen::lock() so that lock() can still flip the internal lock state when the surface starts visible in the undecided state.
  • Change Helper::setLockScreenImpl() to show the lockscreen surface directly (setVisible(true)) instead of immediately switching to the full greeter UI, establishing the undecided startup state.
  • Update Helper::showLockScreen() to guard on GreeterProxy::isLocked instead of LockScreen::isLocked (isVisible) so the undecided state does not prevent a proper transition to greeter when requested.
src/core/lockscreen.cpp
src/seat/helper.cpp
Update handling of DDM daemon messages to exit the undecided state correctly for both explicit greeter display and direct user activation/autologin.
  • Handle DaemonMessages::ShowGreeter by calling Helper::showLockScreen(false) to perform the standard full greeter transition (LockScreen mode, hidden workspace).
  • In GreeterProxy::setLock(true), clear m_undecided and emit undecidedChanged(false) when transitioning to the locked state so the UI no longer treats the session as undecided.
  • In DaemonMessages::UserActivateMessage handling, clear the undecided state, explicitly unlock and hide the lockscreen surface if visible, and then call setLock(false) to ensure the greeter is fully hidden during autologin/unlock flows even if onSessionNew does not fire.
src/greeter/greeterproxy.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@glyvut
glyvut force-pushed the greet branch 3 times, most recently from d14299e to b6d0a70 Compare August 21, 2026 03:51
@glyvut
glyvut marked this pull request as ready for review August 21, 2026 03:51

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @glyvut, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-wm

Copy link
Copy Markdown
Contributor

PR 审查结果

对 treeland #1305 + ddm #106 的联合审查中,treeland 部分的审查结论如下。整体方案连贯,无阻断性问题。

交互流程验证

三条路径均自洽:

  • 自动登录成功:ddm connected()startAutologin()startUserSession()activateSession()TreelandDisplayServer::activateUser() 发送 UserActivateMessage → treeland 隐藏 greeter。✓
  • 自动登录未启用/失败:ddm connected() 发送 ShowGreeter → treeland showLockScreen(false) 显示登录界面。✓
  • DDM 超时/崩溃:treeland 5s 兜底定时器 → lock()setLock(true) 显示登录界面。✓

设计合理的部分

  • undecided 状态设计连贯:壁纸可见、登录 UI 隐藏、5s 兜底定时器。
  • ShowGreetershowLockScreen(false) 正确切换到完整锁屏模式。
  • UserActivateMessage 处理器正确清除 undecided 并隐藏 surface(注释说明了为何 undecided 状态下 setLock(false) 单独无效——m_isLocked 为 false,需显式 setVisible(false) + unlock)。
  • strncmp(service, "ddm", 3) 正确匹配 ddmddm-autologin 两种 session。
  • showLockScreen() 守卫从 m_lockScreen->isLocked()(即 isVisible(),undecided 时为 true)改为 m_greeterProxy->isLocked()——正确修复。
  • LockScreen::lock() 移除 early-return 安全(setLock(true)!m_isLocked 守卫)。
  • UserInput.qml 免密登录 UI:隐藏密码框、显示登录按钮、发送空密码——与 nopasswdlogin PAM 路径配合正确。

需要处理的问题

  1. 兜底定时器从未停止。 m_undecidedTimer 在构造函数启动后从未调用 stop()ShowGreeter/UserActivateMessage/setLock(true) 清除 m_undecided 后,定时器仍会在 5s 后触发——回调检查 if (m_undecided) 后 no-op,功能无害,但应在离开 undecided 状态时停止定时器。

  2. UserModel::updateUserLoginStatedataChanged 索引计算错误(预存 bug)。 std::distance(d->users.end(), user) 返回负值,应为 std::distance(d->users.begin(), user)dataChanged 携带无效索引、实际失效,靠紧随其后的 layoutChanged() 补偿。此 bug 非本 PR 引入,但本 PR 新增的 tryAddNssUser 路径会经过此处。

  3. NSS 新增用户的 noPasswdLogin 始终为 false(次要)。 tryAddNssUser 使用无 Accounts DBus 接口的构造函数创建 UsernoPasswdLogin 硬编码 false。nopasswdlogin 组中的 NSS/LDAP 用户不会显示免密登录按钮。属边缘场景,建议加 TODO。

总结

无阻断性问题,建议合入前处理以下可操作项:

  • 离开 undecided 状态时停止兜底定时器。
  • 考虑修复预存的 dataChanged 索引 bug(std::distance(d->users.end(), user).begin())。

@deepin-wm

Copy link
Copy Markdown
Contributor

CI 编译失败修复

根因

src/greeter/greeterproxy.cpp:518 引用了 DDM::DaemonMessages::ShowGreeter,该枚举值仅在 ddm PR #106 中定义(尚未合入 master)。CI 中 ddm 从 linuxdeepin/ddm master 构建,缺少该枚举值,导致编译失败:

greeterproxy.cpp:518:30: error: 'ShowGreeter' is not a member of 'DDM::DaemonMessages'

修复方案

更新两个 CI workflow,改为从 ddm PR #106 源码构建(包含 ShowGreeter):

  • treeland-deepin-build.yml: 将 ddm clone 源从 linuxdeepin/ddm 改为 glyvut/ddm(PR feat: add distro logo and hide some buttons #106 head)
  • treeland-archlinux-build.yml: 将 pacman -S ddm 替换为从 glyvut/ddm 源码构建 ddm + 安装构建依赖

修复 PR

已创建交叉 fork PR:glyvut#3

该 PR 基于当前 PR #1305greet 分支,仅包含 CI workflow 修复(2 个文件,+19/-5)。合并后 CI 即可重新触发。

合入顺序

ddm PR #106 必须先合入,这是 treeland PR #1305 的前置依赖。ddm PR #106 合入 master 后,本 PR 的 CI 修复可恢复为使用 linuxdeepin/ddm master。

Add an undecided state so the greeter shows the wallpaper but keeps
the login UI hidden until DDM decides between autologin and showing
the greeter, with a 5s fallback timer.

为greeter增加undecided待决状态:先显示壁纸但隐藏登录界面,等待
DDM决定自动登录还是显示登录界面,并设置5秒兜底定时器防止停留在
壁纸。同时处理ShowGreeter消息和用户激活时的界面切换逻辑。

PMS: BUG-294419
Log: 支持自动登录待决状态
Influence: 自动登录时不会闪现登录界面;DDM未决策时5秒后兜底显示登录界面。
@deepin-bot

deepin-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.9.0
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1312

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants