From 415a0c3a3d71f6eae122da0e76561c9ed569f7f0 Mon Sep 17 00:00:00 2001 From: liujiangtao Date: Wed, 16 Sep 2026 16:33:36 +0800 Subject: [PATCH] feat(lockscreen): add power actions to shutdown view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge PowerList into ShutdownView with shutdown, reboot, suspend, hibernate and lock/switch/logout buttons. Adjust focus logic to skip hidden or disabled buttons when opening the power panel. 将关机面板重构成ShutdownView,支持关机/重启/挂起/休眠 及锁屏,切换用户/注销操作,移除原PowerList组件。打开 电源面板时聚焦逻辑会跳过不可见或不可用的按钮。 Log: 重构锁屏关机面板并增加电源操作按钮 PMS: TASK-390751 Influence: 锁屏关机界面提供关机、重启、挂起、休眠等完整 电源操作;电源面板打开时聚焦第一个可见且可用的按钮。交互 和键盘焦点导航相应调整。 --- src/plugins/lockscreen/CMakeLists.txt | 1 - src/plugins/lockscreen/qml/ControlAction.qml | 28 +--- src/plugins/lockscreen/qml/LoginView.qml | 1 + src/plugins/lockscreen/qml/PowerList.qml | 113 --------------- src/plugins/lockscreen/qml/ShutdownView.qml | 130 ++++++++++++------ .../translations/lockscreen.en_US.ts | 43 +++--- 6 files changed, 118 insertions(+), 198 deletions(-) delete mode 100644 src/plugins/lockscreen/qml/PowerList.qml diff --git a/src/plugins/lockscreen/CMakeLists.txt b/src/plugins/lockscreen/CMakeLists.txt index 8eeac1d5e7..d18a52b32f 100644 --- a/src/plugins/lockscreen/CMakeLists.txt +++ b/src/plugins/lockscreen/CMakeLists.txt @@ -25,7 +25,6 @@ qt_add_qml_module(lockscreen qml/Greeter.qml qml/LockView.qml qml/LoginView.qml - qml/PowerList.qml qml/RoundBlur.qml qml/ShutdownButton.qml qml/TimeDateWidget.qml diff --git a/src/plugins/lockscreen/qml/ControlAction.qml b/src/plugins/lockscreen/qml/ControlAction.qml index 10a65d34ac..8e062506b4 100644 --- a/src/plugins/lockscreen/qml/ControlAction.qml +++ b/src/plugins/lockscreen/qml/ControlAction.qml @@ -14,7 +14,7 @@ RowLayout { required property Item rootItem property int buttonSize: 30 - property bool powerVisible: powerList.visible + property bool powerVisible: powerShutdownView.visible signal otherUserRequested() @@ -79,36 +79,20 @@ RowLayout { text: qsTr("Power") } - Item { - id: powerList + ShutdownView { + id: powerShutdownView parent: rootItem visible: powerItem.expand width: rootItem.width height: rootItem.height x: 0 y: 0 - - // Click outside the PowerList to close - MouseArea { - anchors.fill: parent - onClicked: { - powerItem.expand = false - innerPowerList.loopInside = false - } - } - - PowerList { - id: innerPowerList - width: rootItem.width - height: 140 - x: 0 - y: rootItem.height / 5 * 2 - } + onOutsideClicked: powerItem.expand = false + onSwitchUser: bottomGroup.otherUserRequested() } onClicked: { powerItem.expand = true - innerPowerList.focusPowerOff() - innerPowerList.enableLoopInside() + powerShutdownView.focusFirstButton() } } diff --git a/src/plugins/lockscreen/qml/LoginView.qml b/src/plugins/lockscreen/qml/LoginView.qml index 783b1b7b65..7df195c4a9 100644 --- a/src/plugins/lockscreen/qml/LoginView.qml +++ b/src/plugins/lockscreen/qml/LoginView.qml @@ -42,6 +42,7 @@ FocusScope { onSwitchUser: { root.switchUser() } + onOutsideClicked: GreeterProxy.showShutdownView = false } } diff --git a/src/plugins/lockscreen/qml/PowerList.qml b/src/plugins/lockscreen/qml/PowerList.qml deleted file mode 100644 index e5110905ab..0000000000 --- a/src/plugins/lockscreen/qml/PowerList.qml +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2023-2026 UnionTech Software Technology Co., Ltd. -// SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only - -import QtQuick -import Treeland -import LockScreen -import org.deepin.dtk 1.0 as D -import QtQuick.Controls -import QtQuick.Layouts - -FocusScope { - id: root - property alias modelChildren: objModel.children - property alias leftModelChildren: leftObjeModel.children - - property alias listPowerOffBtn: powerOffBtn - property alias listHibernateBtn: hibernateBtn - - property bool loopInside: false - - signal tabOutForward() - signal tabOutBackward() - - implicitWidth: layout.width - implicitHeight: layout.height - - function focusPowerOff() { - powerOffBtn.forceActiveFocus() - } - function focusHibernate() { - hibernateBtn.forceActiveFocus() - } - function enableLoopInside() { - loopInside = true - } - - RowLayout { - id: layout - spacing: 100 - anchors.centerIn: parent - Repeater { - model: ObjectModel { - id: leftObjeModel - } - } - Repeater { - model: ObjectModel { - id: objModel - - ShutdownButton { - id: powerOffBtn - enabled: GreeterProxy.canPowerOff - text: qsTr("Shut Down") - icon.name: "login_shutdown" - onClicked: GreeterProxy.powerOff() - KeyNavigation.tab: rebootBtn - KeyNavigation.backtab: hibernateBtn - Keys.onBacktabPressed: function(event) { - if(root.loopInside){ - event.accepted = false - } - else{ - root.tabOutBackward() - event.accepted = true - } - } - } - - ShutdownButton { - id: rebootBtn - enabled: GreeterProxy.canReboot - text: qsTr("Reboot") - icon.name: "login_reboot" - onClicked: GreeterProxy.reboot() - KeyNavigation.tab: suspendBtn - KeyNavigation.backtab: powerOffBtn - } - - ShutdownButton { - id: suspendBtn - enabled: GreeterProxy.canSuspend - text: qsTr("Suspend") - icon.name: "login_suspend" - onClicked: { - GreeterProxy.suspend() - } - KeyNavigation.tab: hibernateBtn - KeyNavigation.backtab: rebootBtn - } - - ShutdownButton { - id: hibernateBtn - enabled: GreeterProxy.canHibernate - text: qsTr("Hibernate") - icon.name: "login_hibernate" - onClicked: { - GreeterProxy.hibernate() - } - KeyNavigation.tab: powerOffBtn - KeyNavigation.backtab: suspendBtn - Keys.onTabPressed: function(event) { - if(root.loopInside) { - event.accepted = false - } else { - root.tabOutForward() - event.accepted = true - } - } - } - } - } - } -} diff --git a/src/plugins/lockscreen/qml/ShutdownView.qml b/src/plugins/lockscreen/qml/ShutdownView.qml index ad40a44dcd..c5742080fb 100644 --- a/src/plugins/lockscreen/qml/ShutdownView.qml +++ b/src/plugins/lockscreen/qml/ShutdownView.qml @@ -4,63 +4,115 @@ import QtQuick import Treeland import QtQuick.Controls +import QtQuick.Layouts FocusScope { id: root signal switchUser() + signal outsideClicked() Component.onCompleted: { - lockBtn.forceActiveFocus() + if (root.visible) { + focusFirstButton() + } + } + + function focusFirstButton() { + const buttons = GreeterProxy.isLocked + ? [powerOffBtn, rebootBtn, suspendBtn, hibernateBtn] + : [lockBtn, switchBtn, logoutBtn] + for (let btn of buttons) { + if (btn.visible && btn.enabled) { + btn.forceActiveFocus() + return + } + } } MouseArea { anchors.fill: parent - enabled: true - onClicked: GreeterProxy.showShutdownView = false + onClicked: root.outsideClicked() } - PowerList { - id: powerList - onTabOutForward: lockBtn.forceActiveFocus() - onTabOutBackward: logoutBtn.forceActiveFocus() - width: parent.width - height: 140 + RowLayout { + id: layout + spacing: 100 anchors { top: parent.top topMargin: parent.height / 5 * 2 horizontalCenter: parent.horizontalCenter } - modelChildren: [ - ShutdownButton { - id: lockBtn - visible: !GreeterProxy.isLocked - text: qsTr("lock") - icon.name: "login_lock" - onClicked: GreeterProxy.lock() - KeyNavigation.tab: switchBtn - KeyNavigation.backtab: powerList.listHibernateBtn - }, - ShutdownButton { - id: switchBtn - visible: !GreeterProxy.isLocked - text: qsTr("switch user") - icon.name: "login_switchuser" - enabled: UserModel.count > 1 - onClicked: root.switchUser() - KeyNavigation.tab: logoutBtn - KeyNavigation.backtab: lockBtn - }, - ShutdownButton { - id: logoutBtn - visible: !GreeterProxy.isLocked - text: qsTr("Logout") - icon.name: "login_logout" - onClicked: GreeterProxy.logout() - KeyNavigation.tab: powerList.listPowerOffBtn - KeyNavigation.backtab: switchBtn - } - ] + ShutdownButton { + id: powerOffBtn + enabled: GreeterProxy.canPowerOff + text: qsTr("Shut Down") + icon.name: "login_shutdown" + onClicked: GreeterProxy.powerOff() + KeyNavigation.tab: rebootBtn + KeyNavigation.backtab: logoutBtn + } + + ShutdownButton { + id: rebootBtn + enabled: GreeterProxy.canReboot + text: qsTr("Reboot") + icon.name: "login_reboot" + onClicked: GreeterProxy.reboot() + KeyNavigation.tab: suspendBtn + KeyNavigation.backtab: powerOffBtn + } + + ShutdownButton { + id: suspendBtn + enabled: GreeterProxy.canSuspend + text: qsTr("Suspend") + icon.name: "login_suspend" + onClicked: GreeterProxy.suspend() + KeyNavigation.tab: hibernateBtn + KeyNavigation.backtab: rebootBtn + } + + ShutdownButton { + id: hibernateBtn + enabled: GreeterProxy.canHibernate + text: qsTr("Hibernate") + icon.name: "login_hibernate" + onClicked: GreeterProxy.hibernate() + KeyNavigation.tab: lockBtn + KeyNavigation.backtab: suspendBtn + } + + ShutdownButton { + id: lockBtn + visible: !GreeterProxy.isLocked + text: qsTr("lock") + icon.name: "login_lock" + onClicked: GreeterProxy.lock() + KeyNavigation.tab: switchBtn + KeyNavigation.backtab: hibernateBtn + } + + ShutdownButton { + id: switchBtn + visible: !GreeterProxy.isLocked + text: qsTr("switch user") + icon.name: "login_switchuser" + enabled: UserModel.count > 1 + onClicked: root.switchUser() + KeyNavigation.tab: logoutBtn + KeyNavigation.backtab: lockBtn + } + + ShutdownButton { + id: logoutBtn + visible: !GreeterProxy.isLocked + text: qsTr("Logout") + icon.name: "login_logout" + onClicked: GreeterProxy.logout() + KeyNavigation.tab: powerOffBtn + KeyNavigation.backtab: switchBtn + } } } diff --git a/src/plugins/lockscreen/translations/lockscreen.en_US.ts b/src/plugins/lockscreen/translations/lockscreen.en_US.ts index 2407e9cdf9..2759b24044 100644 --- a/src/plugins/lockscreen/translations/lockscreen.en_US.ts +++ b/src/plugins/lockscreen/translations/lockscreen.en_US.ts @@ -18,44 +18,41 @@ - PowerList + ShutdownView - - Hibernate - Hibernate + + lock + - - Suspend - Suspend + + switch user + - - Reboot - Reboot + + Logout + - + Shut Down Shut Down - - - ShutdownView - - lock - + + Reboot + Reboot - - switch user - + + Suspend + Suspend - - Logout - + + Hibernate + Hibernate