Skip to content

Conversation

@calsys456
Copy link
Collaborator

@calsys456 calsys456 commented Dec 12, 2025

This commit is boundled with a ddm update commit.

Summary by Sourcery

Ensure dde-session is correctly reactivated when the compositor restarts or recovers from a crash and propagate existing user login state with session identifiers after daemon recovery.

Bug Fixes:

  • Trigger fd activation on compositor DBus owner changes with a short delay to handle compositor restarts or crash recovery.
  • Emit userLoggedIn with the associated session ID when receiving UserLoggedIn messages during crash recovery so existing sessions are restored correctly.

This commit is boundled with a ddm update commit.
@deepin-ci-robot
Copy link

Hi @calsys456. Thanks for your PR.

I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 12, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts D-Bus watching logic to reliably activate the compositor socket after ddm restart/crash, and enhances greeter crash-recovery handling by propagating session ID when a user is already logged in.

Sequence diagram for compositor socket activation after ddm restart

sequenceDiagram
    participant SystemdSocket as systemd_socket_process
    participant QDBus as qdbus_connection
    participant Compositor as org_deepin_Compositor1

    SystemdSocket->>QDBus: register QDBusServiceWatcher(Compositor1, WatchForOwnerChange)
    SystemdSocket->>QDBus: connect SessionChanged signal to SignalReceiver(onSessionChanged)
    SystemdSocket->>SystemdSocket: activateFd() (initial activation)

    Note over Compositor,QDBus: ddm/compositor crashes and restarts

    Compositor->>QDBus: acquire bus name org.deepin.Compositor1 (owner change)
    QDBus-->>SystemdSocket: serviceOwnerChanged for org.deepin.Compositor1
    SystemdSocket->>SystemdSocket: sleep(1) to wait for compositor readiness
    SystemdSocket->>SystemdSocket: activateFd() (reactivate socket)

    Compositor-->>QDBus: emit SessionChanged
    QDBus-->>SystemdSocket: SessionChanged signal
    SystemdSocket->>SystemdSocket: SignalReceiver.onSessionChanged()
    SystemdSocket->>SystemdSocket: activateFd() (on session change)
Loading

Sequence diagram for greeter crash-recovery user login handling

sequenceDiagram
    participant User as user
    participant DDM as ddm_daemon
    participant Greeter as GreeterProxy
    participant UserModel as UserModel
    participant Session as dde_session

    Note over User,DDM: User is already logged in before crash

    Note over DDM,Greeter: After crash recovery, ddm reconnects to greeter
    DDM->>Greeter: DaemonMessages.UserLoggedIn(user, sessionId)
    Greeter->>Greeter: readyRead() parses user and sessionId

    Greeter->>UserModel: getUser(user)
    UserModel-->>Greeter: userPtr
    alt user found
        Greeter->>UserModel: userPtr.setLogined(true)
        Greeter->>UserModel: emit userLoggedIn(user, sessionId)
        UserModel->>Session: re-associate greeter with existing sessionId
    else user not found
        Greeter->>Greeter: log warning user not found
    end
Loading

Class diagram for updated greeter login handling

classDiagram
    class GreeterProxy {
        +void readyRead()
        -void handleUserLoggedIn(QString user, int sessionId)
    }

    class UserModel {
        +shared_ptr<User> getUser(QString name)
        +void userLoggedIn(QString user, int sessionId)
    }

    class User {
        +void setLogined(bool logined)
    }

    GreeterProxy --> UserModel : uses
    UserModel --> User : manages
    UserModel : signal userLoggedIn(QString user, int sessionId)
Loading

File-Level Changes

Change Details Files
Ensure compositor socket activation reacts to owner changes and waits briefly for compositor readiness.
  • Change QDBusServiceWatcher to watch for service owner changes instead of just registrations
  • Update connection from serviceRegistered signal to serviceOwnerChanged signal
  • Wrap activateFd invocation in a lambda that sleeps briefly before calling it to allow the compositor to be fully ready
  • Keep listening to SessionChanged and calling activateFd on session changes, plus perform an initial activateFd call at startup
src/systemd-socket.cpp
Propagate session information when handling already-logged-in users on greeter crash recovery.
  • Extend UserLoggedIn message parsing to read a sessionId along with the username
  • On crash recovery for an already-logged-in user, emit userLoggedIn(user, sessionId) from the user model so downstream components get the correct session context
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

@calsys456
Copy link
Collaborator Author

Related with linuxdeepin/ddm#54

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and found some issues that need to be addressed.

  • Blocking the main thread with sleep(1) inside the serviceOwnerChanged lambda can delay all event processing; consider using a QTimer::singleShot to defer activateFd() without blocking.
  • Now that you're watching WatchForOwnerChange, the slot will be invoked for both appearance and disappearance of the service; if you only want to react on (re)registration, consider checking the newOwner parameter in the serviceOwnerChanged handler before calling activateFd().
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Blocking the main thread with `sleep(1)` inside the `serviceOwnerChanged` lambda can delay all event processing; consider using a `QTimer::singleShot` to defer `activateFd()` without blocking.
- Now that you're watching `WatchForOwnerChange`, the slot will be invoked for both appearance and disappearance of the service; if you only want to react on (re)registration, consider checking the `newOwner` parameter in the `serviceOwnerChanged` handler before calling `activateFd()`.

## Individual Comments

### Comment 1
<location> `src/systemd-socket.cpp:154` </location>
<code_context>
-                         activateFd);
-
-        // Listen to SessionChanged signal and activate fd when session changed
+                         [&] {
+                             sleep(1); // wait for compositor to be ready
+                             activateFd();
</code_context>

<issue_to_address>
**issue (bug_risk):** The lambda signature is incompatible with QDBusServiceWatcher::serviceOwnerChanged

`serviceOwnerChanged` emits three `QString` arguments (`service`, `oldOwner`, `newOwner`), but this lambda takes none, so its signature is incompatible and the `connect` will not compile or work correctly. Please update the lambda to accept the three parameters (even if unused), e.g. `[&](const QString &, const QString &, const QString &) { ... }`.
</issue_to_address>

### Comment 2
<location> `src/systemd-socket.cpp:155` </location>
<code_context>
-
-        // Listen to SessionChanged signal and activate fd when session changed
+                         [&] {
+                             sleep(1); // wait for compositor to be ready
+                             activateFd();
+                         });
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Blocking `sleep(1)` in the signal handler can stall the event loop

`sleep(1)` here blocks the thread processing DBus signals (likely the main event loop), freezing UI and delaying other handlers. Use a non-blocking delay, e.g. `QTimer::singleShot(1000, this, &::activateFd);`, so the event loop stays responsive.

Suggested implementation:

```cpp
        QObject::connect(compositorWatcher,
                         &QDBusServiceWatcher::serviceOwnerChanged,
                         compositorWatcher,
                         [&] {
                             // Use a non-blocking delay so the DBus/event loop thread stays responsive
                             QTimer::singleShot(1000, [&] {
                                 activateFd();
                             });
                         });

```

1. Ensure the file includes the QTimer header near the top of `src/systemd-socket.cpp`:
   - `#include <QTimer>`
2. If your project uses forward declarations or a precompiled header for Qt widgets/core, make sure QTimer is available there instead of (or in addition to) a local include.
</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.

@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: calsys456, zccrs

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

@zccrs zccrs merged commit 723ac6a into linuxdeepin:master Dec 15, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants