Skip to content

fix(shortcut): skip ddm default session when counting display sessions#92

Open
yixinshark wants to merge 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/power-greeter-session-misjudge
Open

fix(shortcut): skip ddm default session when counting display sessions#92
yixinshark wants to merge 1 commit into
linuxdeepin:masterfrom
yixinshark:fix/power-greeter-session-misjudge

Conversation

@yixinshark

@yixinshark yixinshark commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • hasMultipleDisplaySession() counted org.freedesktop.DisplayManager Sessions and treated >= 2 as multiple users logged in.
  • On Wayland the default display manager (ddm) keeps a dde session alive alongside the user session, so a single login already exposes two sessions — the greeter session's UserName is dde. This misjudged a single user as multiple sessions and wrongly gated shutdown/suspend confirmation.
  • Fix: query each session's UserName and skip the dde greeter before counting. On X11 there is no such dde session, so the filter is a no-op there.

Verification

On a Treeland/ddm machine with a single user logged in, org.freedesktop.DisplayManager.Sessions returns two paths:

  • /org/freedesktop/DisplayManager/Session → UserName dde (default)
  • /org/freedesktop/DisplayManager/Session0 → UserName uos (real user)

After the fix, only the real session is counted, so a single user no longer trips the >= 2 check; a second real login still does.

Summary by Sourcery

Bug Fixes:

  • Prevent shutdown/suspend confirmation from being incorrectly gated when only a single user is logged in but a ddm greeter session is also present.

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: yixinshark

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 Jun 25, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adjusts the display session counting logic to ignore the ddm greeter session identified by UserName "dde" so that power actions are only gated when multiple real user sessions are present.

Sequence diagram for updated display session counting in hasMultipleDisplaySession

sequenceDiagram
    participant PowerController
    participant DisplayManager
    participant DisplayManagerSession

    PowerController->>DisplayManager: property(Sessions)
    DisplayManager-->>PowerController: QList<QDBusObjectPath>

    loop for each QDBusObjectPath
        PowerController->>DisplayManagerSession: QDBusInterface("org.freedesktop.DisplayManager", path.path(), "org.freedesktop.DisplayManager.Session", QDBusConnection::systemBus())
        alt [session is valid]
            PowerController->>DisplayManagerSession: property(UserName)
            DisplayManagerSession-->>PowerController: QString
            alt [UserName == "dde"]
                PowerController-->>PowerController: skip greeter session
            else [UserName != "dde"]
                PowerController-->>PowerController: ++userSessions
            end
        else [session is invalid]
            PowerController-->>PowerController: continue
        end
    end

    PowerController-->>PowerController: return userSessions >= 2
Loading

File-Level Changes

Change Details Files
Refine hasMultipleDisplaySession() to filter out the ddm greeter session when counting active display sessions.
  • Cast the DisplayManager Sessions property once into a QList and iterate over it.
  • For each session, construct a QDBusInterface to org.freedesktop.DisplayManager.Session on the system bus and validate it before use.
  • Read the UserName property for each valid session and skip sessions where UserName equals the greeter account name "dde".
  • Maintain a count of non-greeter sessions and use that count to determine whether there are multiple user sessions (>= 2).
src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.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

@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.

Hey - I've found 1 issue, and left some high level feedback:

  • Consider caching the systemBus QDBusConnection or reusing a single session interface where possible to avoid repeatedly constructing QDBusInterface objects inside the loop for each session.
  • If the underlying DDM implementation changes the greeter UserName from "dde" or introduces additional special sessions, this hard-coded filter could become brittle; you might want to make the greeter identification more robust (e.g., via a dedicated property or configurable list of greeter usernames).
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider caching the systemBus QDBusConnection or reusing a single session interface where possible to avoid repeatedly constructing QDBusInterface objects inside the loop for each session.
- If the underlying DDM implementation changes the greeter UserName from "dde" or introduces additional special sessions, this hard-coded filter could become brittle; you might want to make the greeter identification more robust (e.g., via a dedicated property or configurable list of greeter usernames).

## Individual Comments

### Comment 1
<location path="src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp" line_range="255-254" />
<code_context>
+                               QDBusConnection::systemBus());
+        if (!session.isValid())
+            continue;
+        if (session.property("UserName").toString() == QLatin1String("dde"))
+            continue;
+        ++userSessions;
+    }
</code_context>
<issue_to_address>
**question (bug_risk):** Hardcoding the greeter username "dde" could miscount sessions in some edge cases.

This logic assumes the greeter account is always named `dde` and that no real user account ever uses that name. If either assumption is wrong, real user sessions may be skipped. Please consider a more reliable way to detect greeter sessions (e.g. using a dedicated property or configurable identifier) instead of a hardcoded username.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
hasMultipleDisplaySession() counted org.freedesktop.DisplayManager
Sessions and treated >= 2 as "multiple users logged in". On Wayland the
default display manager (ddm) keeps a dde session alive next to the
user session, so a single logged-in user already exposes two sessions
(session's UserName is "dde"). This misjudged a single user
as multiple sessions, wrongly gating shutdown/suspend confirmation.

Query each session's UserName and skip the "dde" session before
counting, so only real user sessions are tallied. On X11 there is no
such "dde" session, so the filter is a no-op there.

hasMultipleDisplaySession() 通过统计 org.freedesktop.DisplayManager 的
Sessions 数量、以 >= 2 判定"多用户登录"。Wayland 下默认使用的 ddm 会在
用户会话之外保留一个dde会话,因此单个用户登录就已经存在两个
session(UserName 为 "dde"),导致单用户被误判为多会话,
错误地拦截了关机/挂起确认。

改为查询每个会话的 UserName,统计前先跳过 "dde" 会话,只计真实
用户会话。X11 下不存在该 "dde" 会话,过滤为空操作。

Log: skip ddm default session when counting display sessions
Pms: BUG-366665
Change-Id: I6eac98bf68881b5210945cd647b4d4306ef9a255
@yixinshark yixinshark force-pushed the fix/power-greeter-session-misjudge branch from 3195353 to 84240dd Compare June 25, 2026 08:23
@yixinshark yixinshark changed the title fix(shortcut): skip ddm greeter session when counting display sessions fix(shortcut): skip ddm default session when counting display sessions Jun 25, 2026
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:100分

■ 【总体评价】

代码准确修复了Wayland环境下会话计数误判的BUG,逻辑清晰且无副作用
逻辑完全正确且无任何安全与性能隐患,符合满分标准

■ 【详细分析】

  • 1.语法逻辑(完全正确)✓

在PowerController::hasMultipleDisplaySession函数中,通过isWaylandSession()准确区分了X11与Wayland环境,并在Wayland分支中通过遍历过滤掉UserName为"dde"的默认会话,逻辑严密,无语法或编译错误

  • 2.代码质量(良好)✓

代码增加了明确的注释说明过滤原因,变量命名如userSessions语义清晰,且将不同环境下的判断逻辑解耦,符合规范

  • 3.代码性能(无性能问题)✓

虽然在循环中通过DBus获取每个Session的UserName属性,但系统活跃的图形会话数量通常极少(一般1至3个),跨进程调用开销在可接受范围内,不存在性能瓶颈

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
代码仅进行本地DBus属性读取与字符串常量比对,未涉及外部输入处理、命令执行或权限提升,无安全风险

■ 【改进建议代码示例】

// 当前代码已足够优秀,无需额外修改。若未来会话数量剧增,可考虑异步并发获取,但当前场景下无必要。
bool PowerController::hasMultipleDisplaySession()
{
    QVariant v = displayMgr.property("Sessions");
    if (!v.isValid())
        return false;

    const QList<QDBusObjectPath> sessions = qdbus_cast<QList<QDBusObjectPath>>(v);
    if (!isWaylandSession())
        return sessions.size() >= 2;

    // On Treeland the default display manager (ddm) keeps a default session(dde)
    int userSessions = 0;
    for (const QDBusObjectPath &path : sessions) {
        QDBusInterface session("org.freedesktop.DisplayManager", path.path(),
                               "org.freedesktop.DisplayManager.Session",
                               QDBusConnection::systemBus());
        if (!session.isValid())
            continue;
        if (session.property("UserName").toString() == QLatin1String("dde"))
            continue;
        ++userSessions;
    }

    return userSessions >= 2;
}

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.

2 participants