mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
LockScreenTab: implement countdown timer for lockscreen (closes #1456)
This commit is contained in:
@@ -84,7 +84,9 @@
|
||||
"language": "",
|
||||
"allowPanelsOnScreenWithoutBar": true,
|
||||
"showChangelogOnStartup": true,
|
||||
"telemetryEnabled": false
|
||||
"telemetryEnabled": false,
|
||||
"enableLockScreenCountdown": true,
|
||||
"lockScreenCountdownDuration": 10000
|
||||
},
|
||||
"ui": {
|
||||
"fontDefault": "",
|
||||
|
||||
@@ -275,6 +275,8 @@ Singleton {
|
||||
property bool allowPanelsOnScreenWithoutBar: true
|
||||
property bool showChangelogOnStartup: true
|
||||
property bool telemetryEnabled: false
|
||||
property bool enableLockScreenCountdown: true
|
||||
property int lockScreenCountdownDuration: 10000
|
||||
}
|
||||
|
||||
// ui
|
||||
|
||||
@@ -203,6 +203,64 @@ Loader {
|
||||
}
|
||||
}
|
||||
|
||||
// Countdown notification
|
||||
Rectangle {
|
||||
width: countdownRowLayout.implicitWidth + Style.marginXL * 1.5
|
||||
height: 50
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: (Settings.data.general.compactLockScreen ? 280 : 360) * Style.uiScaleRatio
|
||||
radius: Style.radiusL
|
||||
color: Color.mSurface
|
||||
visible: panelComponent.timerActive
|
||||
opacity: visible ? 1.0 : 0.0
|
||||
|
||||
RowLayout {
|
||||
id: countdownRowLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
NIcon {
|
||||
icon: "clock"
|
||||
pointSize: Style.fontSizeXL
|
||||
color: Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: I18n.tr("session-menu.action-in-seconds", {
|
||||
"action": I18n.tr("common." + panelComponent.pendingAction),
|
||||
"seconds": Math.ceil(panelComponent.timeRemaining / 1000)
|
||||
})
|
||||
color: Color.mOnSurface
|
||||
pointSize: Style.fontSizeL
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "x"
|
||||
tooltipText: I18n.tr("session-menu.cancel-timer")
|
||||
baseSize: 32
|
||||
colorBg: Qt.alpha(Color.mPrimary, 0.1)
|
||||
colorFg: Color.mPrimary
|
||||
colorBgHover: Color.mPrimary
|
||||
onClicked: panelComponent.cancelTimer()
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Style.animationNormal
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hidden input that receives actual text
|
||||
TextInput {
|
||||
id: passwordInput
|
||||
|
||||
@@ -26,6 +26,79 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
// Timer properties
|
||||
readonly property int timerDuration: Settings.data.general.lockScreenCountdownDuration
|
||||
property string pendingAction: ""
|
||||
property bool timerActive: false
|
||||
property int timeRemaining: 0
|
||||
|
||||
// Timer management functions
|
||||
function startTimer(action) {
|
||||
// Check if global countdown is disabled
|
||||
if (!Settings.data.general.enableLockScreenCountdown) {
|
||||
executeAction(action);
|
||||
return;
|
||||
}
|
||||
|
||||
if (timerActive && pendingAction === action) {
|
||||
// Second click - execute immediately
|
||||
executeAction(action);
|
||||
return;
|
||||
}
|
||||
|
||||
pendingAction = action;
|
||||
timeRemaining = timerDuration;
|
||||
timerActive = true;
|
||||
countdownTimer.start();
|
||||
}
|
||||
|
||||
function cancelTimer() {
|
||||
timerActive = false;
|
||||
pendingAction = "";
|
||||
timeRemaining = 0;
|
||||
countdownTimer.stop();
|
||||
}
|
||||
|
||||
function executeAction(action) {
|
||||
// Stop timer but don't reset other properties yet
|
||||
countdownTimer.stop();
|
||||
|
||||
// Execute the action
|
||||
switch (action) {
|
||||
case "logout":
|
||||
CompositorService.logout();
|
||||
break;
|
||||
case "suspend":
|
||||
CompositorService.suspend();
|
||||
break;
|
||||
case "hibernate":
|
||||
CompositorService.hibernate();
|
||||
break;
|
||||
case "reboot":
|
||||
CompositorService.reboot();
|
||||
break;
|
||||
case "shutdown":
|
||||
CompositorService.shutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset timer state
|
||||
cancelTimer();
|
||||
}
|
||||
|
||||
// Countdown timer
|
||||
Timer {
|
||||
id: countdownTimer
|
||||
interval: 100
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
timeRemaining -= interval;
|
||||
if (timeRemaining <= 0) {
|
||||
executeAction(pendingAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compact status indicators container (compact mode only)
|
||||
Rectangle {
|
||||
width: {
|
||||
@@ -666,7 +739,7 @@ Item {
|
||||
iconSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
buttonRadius: Style.radiusL
|
||||
onClicked: CompositorService.logout()
|
||||
onClicked: startTimer("logout")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -686,7 +759,7 @@ Item {
|
||||
iconSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
buttonRadius: Style.radiusL
|
||||
onClicked: CompositorService.suspend()
|
||||
onClicked: startTimer("suspend")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +780,7 @@ Item {
|
||||
iconSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
buttonRadius: Style.radiusL
|
||||
onClicked: CompositorService.hibernate()
|
||||
onClicked: startTimer("hibernate")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,7 +800,7 @@ Item {
|
||||
iconSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
buttonRadius: Style.radiusL
|
||||
onClicked: CompositorService.reboot()
|
||||
onClicked: startTimer("reboot")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +820,7 @@ Item {
|
||||
iconSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
buttonRadius: Style.radiusL
|
||||
onClicked: CompositorService.shutdown()
|
||||
onClicked: startTimer("shutdown")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,35 @@ ColumnLayout {
|
||||
visible: Settings.data.general.showSessionButtonsOnLockScreen
|
||||
defaultValue: Settings.getDefaultValue("general.showSessionButtonsOnLockScreen")
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("panels.session-menu.enable-countdown-label")
|
||||
description: I18n.tr("panels.session-menu.enable-countdown-description")
|
||||
checked: Settings.data.general.enableLockScreenCountdown
|
||||
onToggled: checked => Settings.data.general.enableLockScreenCountdown = checked
|
||||
visible: Settings.data.general.showSessionButtonsOnLockScreen
|
||||
defaultValue: Settings.getDefaultValue("general.enableLockScreenCountdown")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: Settings.data.general.showSessionButtonsOnLockScreen && Settings.data.general.enableLockScreenCountdown
|
||||
spacing: Style.marginXXS
|
||||
Layout.fillWidth: true
|
||||
|
||||
NLabel {
|
||||
label: I18n.tr("panels.session-menu.countdown-duration-label")
|
||||
description: I18n.tr("panels.session-menu.countdown-duration-description")
|
||||
}
|
||||
|
||||
NValueSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 1000
|
||||
to: 30000
|
||||
stepSize: 1000
|
||||
value: Settings.data.general.lockScreenCountdownDuration
|
||||
onMoved: value => Settings.data.general.lockScreenCountdownDuration = value
|
||||
text: Math.round(Settings.data.general.lockScreenCountdownDuration / 1000) + "s"
|
||||
defaultValue: Settings.getDefaultValue("general.lockScreenCountdownDuration")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user