Skip to content

fix: implement Wayland screen-off in systemTurnOffScreen#89

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
deepin-wm:fix/wayland-turn-off-screen
Jun 24, 2026
Merged

fix: implement Wayland screen-off in systemTurnOffScreen#89
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
deepin-wm:fix/wayland-turn-off-screen

Conversation

@deepin-wm

@deepin-wm deepin-wm commented Jun 18, 2026

Copy link
Copy Markdown

Summary

Replace the TODO placeholder in systemTurnOffScreen() Wayland branch with a working implementation for Treeland/Wayland.

Changes

  1. Replace TODO placeholder in systemTurnOffScreen() Wayland branch
  2. Add doPrepareSuspend()/undoPrepareSuspend() to prevent idle watcher race
  3. Lock screen before turning off if shouldLockOnScreenBlack is true
  4. Call Power1.TurnOffScreen() via DBus for wlr-output-power-management-v1
  5. Add 500ms delay after lock for lock UI rendering

Flow

doPrepareSuspend → shouldLockOnScreenBlack → doLock → msleep(500) → TurnOffScreen(DBus) → undoPrepareSuspend

Related

PMS: BUG-209669
Issue: WM-50

Summary by Sourcery

Implement functional screen-off behavior for Wayland sessions and align session power handling with lock and suspend preparation state.

New Features:

  • Add Wayland/Treeland screen-off support via org.deepin.dde.Power1.TurnOffScreen DBus call.

Bug Fixes:

  • Prevent races between idle watcher and screen-off by coordinating prepare-suspend state around DPMS screen-off.

Enhancements:

  • Lock the screen and introduce a short delay before turning off DPMS to ensure lock UI renders correctly when blacking the screen.

@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

@sourcery-ai

sourcery-ai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements Wayland/Treeland screen-off behavior by delegating systemTurnOffScreen() on Wayland to a Power1 DBus method and updating the session-side PowerManager to coordinate suspend preparation, optional locking, and a brief delay before actually powering off the screen.

Sequence diagram for Wayland systemTurnOffScreen delegation via Power1 DBus

sequenceDiagram
    actor User
    participant PowerController
    participant Power1_DBUS as Power1
    participant PowerManager

    User ->> PowerController: systemTurnOffScreen()
    PowerController ->> PowerController: isWaylandSession()
    alt isWaylandSession
        PowerController ->> Power1_DBUS: power.call(TurnOffScreen)
        Power1_DBUS ->> PowerManager: TurnOffScreen()
        PowerManager ->> PowerManager: TurnOffScreen()
        alt m_screenBlackLock
            PowerManager ->> PowerManager: doLock(true)
        end
        PowerManager ->> PowerManager: QTimer::singleShot(500)
        PowerManager ->> PowerManager: setDPMSModeOff()
    else not Wayland
        PowerController ->> PowerController: systemTurnOffScreen (non Wayland path)
    end
Loading

Flow diagram for PowerManager::TurnOffScreen behavior

flowchart TD
    A["PowerManager::TurnOffScreen"] --> B["log Turning off screen"]
    B --> C["set m_prepareSuspendState = PS_Sleeping"]
    C --> D{m_screenBlackLock?}
    D -- yes --> E["doLock(true)"]
    D -- no --> F["QTimer::singleShot 500ms"]
    E --> F["QTimer::singleShot 500ms"]
    F --> G["setDPMSModeOff()"]
    G --> H["set m_prepareSuspendState = PS_Normal"]
Loading

File-Level Changes

Change Details Files
Coordinate suspend-preparation, optional locking, and delayed DPMS screen-off in PowerManager::TurnOffScreen.
  • Set prepare-suspend state to sleeping before initiating screen-off sequence.
  • Conditionally invoke doLock when screen-black locking is enabled.
  • Use a single-shot QTimer with a 500ms delay before calling setDPMSModeOff.
  • Restore prepare-suspend state back to normal after turning off DPMS.
  • Add structured logging around the screen-off operation.
src/plugin-qt/power/session/powermanager.cpp
Implement Wayland/Treeland screen-off path in systemTurnOffScreen via Power1 DBus API.
  • Replace Wayland TODO branch with a DBus interface call to org.deepin.dde.Power1.TurnOffScreen.
  • Document that the Wayland path handles prepare-suspend, locking, delay, and screen-off inside the Power service.
  • Add validity check on the DBus interface and warn when Power1 is unavailable.
  • Keep existing non-Wayland behavior unchanged.
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

@deepin-wm deepin-wm force-pushed the fix/wayland-turn-off-screen branch 4 times, most recently from 3dfe9be to 3a66d6b Compare June 22, 2026 06:13
@mhduiy mhduiy marked this pull request as ready for review June 22, 2026 07:57

@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 left some high level feedback:

  • In PowerManager::TurnOffScreen, consider avoiding hard-coded state transitions (PS_SleepingPS_Normal) inside the timer and instead reuse any existing prepare/undo helpers so the suspend state logic stays centralized and consistent with other callers.
  • The 500ms delay before setDPMSModeOff() is currently an inline magic number; pulling this into a named constant (and/or sharing it with the Wayland/Treeland implementation) would make the intent clearer and easier to tune across platforms.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `PowerManager::TurnOffScreen`, consider avoiding hard-coded state transitions (`PS_Sleeping``PS_Normal`) inside the timer and instead reuse any existing prepare/undo helpers so the suspend state logic stays centralized and consistent with other callers.
- The 500ms delay before `setDPMSModeOff()` is currently an inline magic number; pulling this into a named constant (and/or sharing it with the Wayland/Treeland implementation) would make the intent clearer and easier to tune across platforms.

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.

1. Change TurnOffScreen() to call doTurnOffScreen() which
   handles lock + delay + DPMS off internally
2. Replace Wayland TODO placeholder in powercontroller with
   sessionBus DBus call to Power1 TurnOffScreen

Log: Fixed power button screen-off not working on Wayland/Treeland

Influence:
1. Test power button screen-off in Treeland session
2. Verify lock screen appears before display turns off
3. Test wake from screen-off resumes to lock screen
4. Verify X11 screen-off path is not affected

fix: 实现 Wayland 熄屏功能

1. 修改 TurnOffScreen() 调用 doTurnOffScreen(),内部
   已封装锁屏+延迟+熄屏完整流程
2. 替换 powercontroller Wayland TODO 占位为 sessionBus
   DBus 调用 Power1 TurnOffScreen

Log: 修复 Wayland/Treeland 下按电源键熄屏无响应的问题

Influence:
1. 在 Treeland 会话下测试按电源键熄屏功能
2. 验证熄屏前锁屏界面正常显示
3. 测试从熄屏唤醒后回到锁屏界面
4. 验证 X11 熄屏路径不受影响

PMS: BUG-209669
@deepin-wm deepin-wm force-pushed the fix/wayland-turn-off-screen branch from 3a66d6b to 7d768d6 Compare June 23, 2026 10:07
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:85分

■ 【总体评价】

代码修复了Wayland下关闭屏幕的空实现问题,但存在同步D-Bus调用导致的轻微性能隐患
逻辑正确且安全无漏洞,但因同步调用可能引发界面卡顿扣15分

■ 【详细分析】

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

代码移除了原有的TODO注释,在powercontroller.cpp中正确实例化了QDBusInterface对象,并使用isValid()进行了有效性校验后才发起调用。powermanager.cpp中将直接调用重构为doTurnOffScreen()符合抽象封装原则。
潜在问题:无
建议:无

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

代码意图明确,通过D-Bus通信解耦了快捷键模块与电源管理模块的直接依赖,符合桌面组件的模块化设计规范。日志输出区分了qInfo与qWarning,便于问题排查。
潜在问题:无
建议:无

  • 3.代码性能(存在性能问题)✕

在powercontroller.cpp的systemTurnOffScreen函数中,使用了power.call("TurnOffScreen")进行同步D-Bus调用。
潜在问题:若org.deepin.dde.Power1服务由于负载过高或死锁导致响应缓慢,会阻塞发起调用的当前线程。由于该函数由快捷键触发,通常运行在UI或事件处理线程中,同步阻塞会导致桌面环境出现短暂的卡顿或无响应现象。
建议:将同步的power.call替换为异步的power.asyncCall,避免阻塞调用方线程,提升快捷键响应的流畅度。

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

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
总体风险描述:D-Bus调用的服务名、对象路径、接口名及方法名均为硬编码常量,未拼接任何外部输入,不存在注入或越权风险。

  • 建议:保持当前的硬编码调用方式,无需额外安全加固

■ 【改进建议代码示例】

diff --git a/src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp b/src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
index 8d1aa0c..e1a2b3c 100644
--- a/src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
+++ b/src/plugin-qt/shortcut/tools/dde-shortcut-tool/powercontroller.cpp
@@ -412,10 +412,11 @@ void PowerController::systemTurnOffScreen()
 
     if (isWaylandSession()) {
         QDBusInterface power("org.deepin.dde.Power1", "/org/deepin/dde/Power1",
                              "org.deepin.dde.Power1", QDBusConnection::sessionBus());
         if (power.isValid()) {
-            power.call("TurnOffScreen");
+            // 使用异步调用避免阻塞快捷键处理线程
+            power.asyncCall("TurnOffScreen");
         } else {
             qWarning() << "PowerController: Power1 unavailable for TurnOffScreen";
         }
         return;

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: deepin-wm, mhduiy

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

@mhduiy

mhduiy commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

/forcemerge

@deepin-bot

deepin-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

This pr force merged! (status: blocked)

@deepin-bot deepin-bot Bot merged commit b7fbd99 into linuxdeepin:master Jun 24, 2026
8 of 9 checks passed
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