lock: add option to require password for poweroff/reboot (#2085)

This commit is contained in:
end-4
2025-10-03 01:02:03 +02:00
parent 027f9a1793
commit 42913816ce
4 changed files with 152 additions and 96 deletions
@@ -14,6 +14,7 @@ MouseArea {
required property LockContext context
property bool active: false
property bool showInputField: active || context.currentText.length > 0
readonly property bool requirePasswordToPower: Config.options.lock.security.requirePasswordToPower
// Force focus on entry
function forceFieldFocus() {
@@ -73,7 +74,10 @@ MouseArea {
// }
// implicitHeight: 40
// colBackground: Appearance.colors.colLayer2
// onClicked: context.unlocked()
// onClicked: {
// context.unlocked(LockContext.ActionEnum.Unlock);
// GlobalStates.screenLocked = false;
// }
// contentItem: StyledText {
// text: "[[ DEBUG BYPASS ]]"
// }
@@ -136,7 +140,15 @@ MouseArea {
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
iconSize: 24
text: "arrow_right_alt"
text: {
if (root.context.targetAction === LockContext.ActionEnum.Unlock) {
return "arrow_right_alt";
} else if (root.context.targetAction === LockContext.ActionEnum.Poweroff) {
return "power_settings_new";
} else if (root.context.targetAction === LockContext.ActionEnum.Reboot) {
return "restart_alt";
}
}
color: confirmButton.enabled ? Appearance.colors.colOnPrimary : Appearance.colors.colSubtext
}
}
@@ -155,29 +167,14 @@ MouseArea {
opacity: root.toolbarOpacity
// Username
Row {
spacing: 6
IconAndTextPair {
Layout.leftMargin: 8
Layout.fillHeight: true
MaterialSymbol {
id: userIcon
anchors.verticalCenter: parent.verticalCenter
fill: 1
text: "account_circle"
iconSize: Appearance.font.pixelSize.huge
color: Appearance.colors.colOnSurfaceVariant
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: SystemInfo.username
color: Appearance.colors.colOnSurfaceVariant
}
icon: "account_circle"
text: SystemInfo.username
}
// Keyboard layout (Xkb)
Loader {
Layout.leftMargin: 8
Layout.rightMargin: 8
Layout.fillHeight: true
@@ -230,77 +227,94 @@ MouseArea {
scale: root.toolbarScale
opacity: root.toolbarOpacity
Row {
IconAndTextPair {
visible: UPower.displayDevice.isLaptopBattery
spacing: 4
Layout.fillHeight: true
Layout.leftMargin: 10
Layout.rightMargin: 10
MaterialSymbol {
id: boltIcon
anchors {
verticalCenter: parent.verticalCenter
}
fill: 1
text: Battery.isCharging ? "bolt" : "battery_android_full"
iconSize: Appearance.font.pixelSize.huge
animateChange: true
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: Math.round(Battery.percentage * 100)
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
}
icon: Battery.isCharging ? "bolt" : "battery_android_full"
text: Math.round(Battery.percentage * 100)
color: (Battery.isLow && !Battery.isCharging) ? Appearance.colors.colError : Appearance.colors.colOnSurfaceVariant
}
ToolbarButton {
ActionToolbarIconButton {
id: sleepButton
implicitWidth: height
onClicked: Session.suspend()
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
iconSize: 24
text: "dark_mode"
color: Appearance.colors.colOnSurfaceVariant
}
text: "dark_mode"
}
ToolbarButton {
PasswordGuardedActionToolbarIconButton {
id: powerButton
implicitWidth: height
onClicked: Session.poweroff()
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
iconSize: 24
text: "power_settings_new"
color: Appearance.colors.colOnSurfaceVariant
}
text: "power_settings_new"
targetAction: LockContext.ActionEnum.Poweroff
}
ToolbarButton {
PasswordGuardedActionToolbarIconButton {
id: rebootButton
implicitWidth: height
text: "restart_alt"
targetAction: LockContext.ActionEnum.Reboot
}
}
onClicked: Session.reboot()
component PasswordGuardedActionToolbarIconButton: ActionToolbarIconButton {
id: guardedBtn
required property var targetAction
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
iconSize: 24
text: "restart_alt"
color: Appearance.colors.colOnSurfaceVariant
toggled: root.context.targetAction === guardedBtn.targetAction
onClicked: {
if (!root.requirePasswordToPower) {
root.context.unlocked(guardedBtn.targetAction);
return;
}
if (root.context.targetAction === guardedBtn.targetAction) {
root.context.resetTargetAction();
} else {
root.context.targetAction = guardedBtn.targetAction;
root.context.shouldReFocus();
}
}
}
component ActionToolbarIconButton: ToolbarButton {
id: iconBtn
implicitWidth: height
colBackgroundToggled: Appearance.colors.colSecondaryContainer
colBackgroundToggledHover: Appearance.colors.colSecondaryContainerHover
colRippleToggled: Appearance.colors.colSecondaryContainerActive
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
iconSize: 24
text: iconBtn.text
color: iconBtn.toggled ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnSurfaceVariant
}
}
component IconAndTextPair: Row {
id: pair
required property string icon
required property string text
property color color: Appearance.colors.colOnSurfaceVariant
spacing: 4
Layout.fillHeight: true
Layout.leftMargin: 10
Layout.rightMargin: 10
MaterialSymbol {
anchors.verticalCenter: parent.verticalCenter
fill: 1
text: pair.icon
iconSize: Appearance.font.pixelSize.huge
animateChange: true
color: pair.color
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
text: pair.text
color: pair.color
}
}
}