Skip to content

fix(xwayland): X11 apps cannot connect after treeland restart#1047

Draft
wineee wants to merge 1 commit into
linuxdeepin:masterfrom
wineee:x11
Draft

fix(xwayland): X11 apps cannot connect after treeland restart#1047
wineee wants to merge 1 commit into
linuxdeepin:masterfrom
wineee:x11

Conversation

@wineee

@wineee wineee commented Jun 23, 2026

Copy link
Copy Markdown
Member

When treeland restarts, Xwayland generates a new MIT-MAGIC-COOKIE-1 but treeland-sd (xwayland helper) does not update the user's XAUTHORITY, causing "Invalid MIT-MAGIC-COOKIE-1 key" errors for all X11 apps.

Root cause: sessionChanged() was only emitted on user switch, not when the same session's Xwayland was recreated after a restart. treeland-sd listens for this signal to refresh DISPLAY/XAUTHORITY.

Changes:

  • Emit sessionChanged() in WXWayland::ready callback to ensure the xauth cookie is valid before notifying treeland-sd
  • Add Restart=on-failure to treeland-xwayland.service so the helper recovers automatically if treeland restarts causes D-Bus disconnection
  • Add ExecStartPre to treeland.service to kill orphaned Xwayland processes from a crashed previous instance

Fix: #1071

Summary by Sourcery

Improve Xwayland activation robustness and recovery when treeland restarts.

Bug Fixes:

  • Ensure Xwayland activation retries when the compositor D-Bus interface is temporarily unavailable, preventing X11 connection failures after treeland restarts.

Enhancements:

  • Add delayed retry logic for Xwayland activation when the compositor D-Bus interface is not yet ready.

Deployment:

  • Update treeland systemd units to restart the Xwayland helper on failure and clean up orphaned Xwayland processes on treeland startup.

@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 @wineee, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: wineee

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

@wineee wineee marked this pull request as draft June 23, 2026 12:42
@wineee wineee force-pushed the x11 branch 2 times, most recently from eff778f to 125f5b1 Compare June 24, 2026 05:39
@deepin-bot

deepin-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

TAG Bot

New tag: 0.8.13
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #1063

@wineee wineee force-pushed the x11 branch 5 times, most recently from ace6f3b to 64d90c0 Compare June 30, 2026 07:17
@wineee wineee marked this pull request as ready for review June 30, 2026 07:21
@sourcery-ai

sourcery-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Ensures Xwayland helper and environment are correctly updated and resilient after treeland restarts, fixing invalid X11 auth cookies and orphaned processes.

Sequence diagram for treeland-sd retrying XWaylandName after restart

sequenceDiagram
    participant treeland_sd as treeland_sd
    participant Compositor1 as org_deepin_Compositor1
    participant QTimer as QTimer
    participant Systemd as systemd

    loop retry_activateFd
        treeland_sd->>Compositor1: XWaylandName
        alt reply is valid
            treeland_sd->>Compositor1: UpdateActivationEnvironment
            treeland_sd->>Systemd: sd_notify READY=1
        else reply is error
            treeland_sd->>QTimer: QTimer::singleShot(500, app, activateFd)
        end
    end
Loading

File-Level Changes

Change Details Files
Make systemd socket activator resilient to transient Xwayland D-Bus failures so Xwayland name registration is retried.
  • Capture app and self-recursive lambda in active() closure to support delayed re-invocation
  • Handle QDBusMessage::ErrorMessage from XWaylandName call and log detailed warning
  • Schedule a 500ms QTimer retry for type=="xwayland" when the D-Bus interface is invalid, reusing the same activateFd logic
src/systemd-socket.cpp
Harden treeland/xwayland systemd units so helper recovers on compositor restart and cleans up stale Xwayland processes.
  • Add Restart=on-failure to treeland-xwayland.service to auto-recover helper after D-Bus disconnects or crashes
  • Add ExecStartPre to treeland.service that kills orphaned Xwayland instances from previous crashed treeland runs
  • Ensure unit ordering keeps helper and compositor restart semantics aligned with Xwayland lifecycle
misc/systemd/dde-session-pre.target.wants/treeland-xwayland.service.in
misc/systemd/treeland.service.in

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:

  • The recursive use of activateFd with QTimer::singleShot(500, &app, activateFd) for the xwayland case has no retry limit or backoff, so consider adding a maximum retry count or exponential backoff to avoid an infinite retry loop if the compositor never comes up.
  • You're capturing app and activateFd by reference into a lambda that is scheduled for later execution; double-check that their lifetimes are clearly bounded by main and that treeland-sd cannot exit while timers are still queued, or consider encapsulating this logic in an object with explicit lifetime management.
  • The error handling path logs XWaylandName failures but then immediately retries only when updateFd is invalid; consider distinguishing between transient D-Bus errors and permanent failures to avoid noisy retries in cases where the service is misconfigured or unavailable.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The recursive use of `activateFd` with `QTimer::singleShot(500, &app, activateFd)` for the xwayland case has no retry limit or backoff, so consider adding a maximum retry count or exponential backoff to avoid an infinite retry loop if the compositor never comes up.
- You're capturing `app` and `activateFd` by reference into a lambda that is scheduled for later execution; double-check that their lifetimes are clearly bounded by `main` and that treeland-sd cannot exit while timers are still queued, or consider encapsulating this logic in an object with explicit lifetime management.
- The error handling path logs `XWaylandName` failures but then immediately retries only when `updateFd` is invalid; consider distinguishing between transient D-Bus errors and permanent failures to avoid noisy retries in cases where the service is misconfigured or unavailable.

## Individual Comments

### Comment 1
<location path="src/systemd-socket.cpp" line_range="77-79" />
<code_context>

-    auto active = [unixFileDescriptor, type, &tmpFiles](QDBusConnection connection) {
-        auto activateFd = [unixFileDescriptor, type, &connection, &tmpFiles] {
+    auto active = [unixFileDescriptor, type, &tmpFiles, &app](QDBusConnection connection) {
+        std::function<void()> activateFd;
+        activateFd = [unixFileDescriptor, type, connection, &tmpFiles, &app, &activateFd] {
             QDBusInterface updateFd("org.deepin.Compositor1",
                                     "/org/deepin/Compositor1",
</code_context>
<issue_to_address>
**issue (bug_risk):** Recursive lambda captures its own std::function by reference, leading to a dangling reference when used with QTimer::singleShot.

Because the lambda captures `&activateFd`, the `std::function` stored in `activateFd` closes over a stack variable that is destroyed when `active()` returns. Any callbacks scheduled via `QTimer::singleShot` will then invoke a dangling reference, causing undefined behavior.

For safe recursion with `QTimer::singleShot`, ensure the callback does not capture stack references that outlive `active()`. For example, capture by value and move into `singleShot`, or restructure using a helper QObject/free function or a heap-allocated callable (e.g., `std::shared_ptr<std::function<void()>>`) with a lifetime that exceeds `active()`.
</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/systemd-socket.cpp Outdated
@wineee wineee force-pushed the x11 branch 4 times, most recently from f22e635 to 49b103d Compare June 30, 2026 08:09
When treeland restarts, Xwayland generates a new MIT-MAGIC-COOKIE-1 but
treeland-sd does not update the user's XAUTHORITY, causing auth failures.

Replace the xwaylandDisplayChanged signal approach with a simpler retry
mechanism: when treeland is not yet available on D-Bus, retry the
XWaylandName query every 500ms until it succeeds. This handles both
initial startup and treeland restart without requiring a new D-Bus signal.

问题

treeland 重启后,X11 应用报 Invalid MIT-MAGIC-COOKIE-1 key 无法连接 Xwayland。

原因

Xwayland 使用 MIT-MAGIC-COOKIE-1 认证。连接流程是:
1. treeland-xwayland helper 生成随机 cookie → 写入 /tmp/.xauth_:1
2. treeland-sd 通过 D-Bus 调用 XWaylandName() 读取 cookie → 写入用户的 $XAUTHORITY 文件
3. X11 客户端连接 Xwayland 时出示 cookie 进行认证
treeland 重启后,Xwayland 生成新的 cookie,但 treeland-sd 的 D-Bus 连接已断开(绑定在旧的 name owner 上),无法收到通知去更新用户的 $XAUTHORITY。导致用户环境中的 cookie 是旧的,认证失败。

修复

misc/systemd/treeland.service.in
- 添加 ExecStartPre,启动前清理上次崩溃遗留的孤儿 Xwayland 进程

misc/systemd/dde-session-pre.target.wants/treeland-xwayland.service.in
- 添加 Restart=on-failure,treeland-sd 进程异常退出后自动重启

src/systemd-socket.cpp
- 添加重试机制:当 treeland 还未在 D-Bus 上注册时,每 500ms 重试 XWaylandName() 查询,直到成功
- 这样无论是首次启动、treeland 重启、还是 D-Bus 信号丢失,都能可靠地获取最新的 cookie 并更新 systemd 用户环境变量

ISSUE: 1071
@wineee wineee marked this pull request as draft June 30, 2026 08:33
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.

Treeland 崩溃恢复后 xwayland 无法使用

2 participants