summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock
diff options
context:
space:
mode:
authorNippy <nippy@rp1.hu>2026-05-09 13:33:09 +0200
committerNippy <nippy@rp1.hu>2026-05-09 13:33:09 +0200
commita2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5 (patch)
tree1a8769217f84bfe9d6216fafaadaf8cdd876d457 /raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock
parent34b9c34f982b2596cfa9e368a2d7f74e9a17477c (diff)
downloadRaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.tar.gz
RaveOS-PKGBUILD-a2b924d7e9492b978ad6dc33b6c1ffcb304b4bc5.zip
raveos update
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock')
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/CustomButtonKeyboard.qml41
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToDpmsWindow.qml102
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToLockWindow.qml102
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Keyboard.qml344
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/KeyboardController.qml40
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Lock.qml296
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockPowerMenu.qml820
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenContent.qml1707
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenDemo.qml46
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockSurface.qml73
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Pam.qml405
-rw-r--r--raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/VideoScreensaver.qml200
12 files changed, 0 insertions, 4176 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/CustomButtonKeyboard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/CustomButtonKeyboard.qml
deleted file mode 100644
index 639389c..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/CustomButtonKeyboard.qml
+++ /dev/null
@@ -1,41 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-DankActionButton {
- id: customButtonKeyboard
- circular: false
- property string text: ""
- width: 40
- height: 40
- property bool isShift: false
- color: Theme.surface
-
- property bool isIcon: text === "keyboard_hide" || text === "Backspace" || text === "Enter"
-
- DankIcon {
- anchors.centerIn: parent
- name: {
- if (parent.text === "keyboard_hide") return "keyboard_hide"
- if (parent.text === "Backspace") return "backspace"
- if (parent.text === "Enter") return "keyboard_return"
- return ""
- }
- size: 20
- color: Theme.surfaceText
- visible: parent.isIcon
- }
-
- StyledText {
- id: contentItem
- anchors.centerIn: parent
- text: parent.text
- color: Theme.surfaceText
- font.pixelSize: Theme.fontSizeXLarge
- font.weight: Font.Normal
- visible: !parent.isIcon
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToDpmsWindow.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToDpmsWindow.qml
deleted file mode 100644
index 0486890..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToDpmsWindow.qml
+++ /dev/null
@@ -1,102 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Wayland
-import qs.Common
-
-PanelWindow {
- id: root
-
- property bool active: false
-
- signal fadeCompleted
- signal fadeCancelled
-
- visible: active
- color: "transparent"
-
- WlrLayershell.namespace: "dms:fade-to-dpms"
- WlrLayershell.layer: WlrLayershell.Overlay
- WlrLayershell.exclusiveZone: -1
- WlrLayershell.keyboardFocus: active ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
-
- anchors {
- left: true
- right: true
- top: true
- bottom: true
- }
-
- Rectangle {
- id: fadeOverlay
- anchors.fill: parent
- color: "black"
- opacity: 0
-
- onOpacityChanged: {
- if (opacity >= 0.99 && root.active) {
- root.fadeCompleted();
- }
- }
- }
-
- SequentialAnimation {
- id: fadeSeq
- running: false
-
- NumberAnimation {
- target: fadeOverlay
- property: "opacity"
- from: 0.0
- to: 1.0
- duration: SettingsData.fadeToDpmsGracePeriod * 1000
- easing.type: Easing.OutCubic
- }
- }
-
- function startFade() {
- if (!SettingsData.fadeToDpmsEnabled)
- return;
- active = true;
- fadeOverlay.opacity = 0.0;
- fadeSeq.stop();
- fadeSeq.start();
- }
-
- function cancelFade() {
- fadeSeq.stop();
- fadeOverlay.opacity = 0.0;
- active = false;
- fadeCancelled();
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: root.active
- onClicked: root.cancelFade()
- onPressed: root.cancelFade()
- }
-
- FocusScope {
- anchors.fill: parent
- focus: root.active
-
- Keys.onPressed: event => {
- root.cancelFade();
- event.accepted = true;
- }
- }
-
- Component.onCompleted: {
- if (active) {
- forceActiveFocus();
- }
- }
-
- onActiveChanged: {
- if (active) {
- forceActiveFocus();
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToLockWindow.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToLockWindow.qml
deleted file mode 100644
index c73a59a..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/FadeToLockWindow.qml
+++ /dev/null
@@ -1,102 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Wayland
-import qs.Common
-
-PanelWindow {
- id: root
-
- property bool active: false
-
- signal fadeCompleted
- signal fadeCancelled
-
- visible: active
- color: "transparent"
-
- WlrLayershell.namespace: "dms:fade-to-lock"
- WlrLayershell.layer: WlrLayershell.Overlay
- WlrLayershell.exclusiveZone: -1
- WlrLayershell.keyboardFocus: active ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None
-
- anchors {
- left: true
- right: true
- top: true
- bottom: true
- }
-
- Rectangle {
- id: fadeOverlay
- anchors.fill: parent
- color: "black"
- opacity: 0
-
- onOpacityChanged: {
- if (opacity >= 0.99 && root.active) {
- root.fadeCompleted();
- }
- }
- }
-
- SequentialAnimation {
- id: fadeSeq
- running: false
-
- NumberAnimation {
- target: fadeOverlay
- property: "opacity"
- from: 0.0
- to: 1.0
- duration: SettingsData.fadeToLockGracePeriod * 1000
- easing.type: Easing.OutCubic
- }
- }
-
- function startFade() {
- if (!SettingsData.fadeToLockEnabled)
- return;
- active = true;
- fadeOverlay.opacity = 0.0;
- fadeSeq.stop();
- fadeSeq.start();
- }
-
- function cancelFade() {
- fadeSeq.stop();
- fadeOverlay.opacity = 0.0;
- active = false;
- fadeCancelled();
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: root.active
- onClicked: root.cancelFade()
- onPressed: root.cancelFade()
- }
-
- FocusScope {
- anchors.fill: parent
- focus: root.active
-
- Keys.onPressed: event => {
- root.cancelFade();
- event.accepted = true;
- }
- }
-
- Component.onCompleted: {
- if (active) {
- forceActiveFocus();
- }
- }
-
- onActiveChanged: {
- if (active) {
- forceActiveFocus();
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Keyboard.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Keyboard.qml
deleted file mode 100644
index cfc0c61..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Keyboard.qml
+++ /dev/null
@@ -1,344 +0,0 @@
-import QtQuick
-import qs.Common
-
-Rectangle {
- id: root
- property Item target
- height: 60 * 5
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- color: Theme.surfaceContainerHigh
-
- signal dismissed
-
- property double rowSpacing: 0.01 * width // horizontal spacing between keyboard
- property double columnSpacing: 0.02 * height // vertical spacing between keyboard
- property bool shift: false //Boolean for the shift state
- property bool symbols: false //Boolean for the symbol state
- property double columns: 10 // Number of column
- property double rows: 4 // Number of row
-
- property string strShift: '\u2191'
- property string strBackspace: "Backspace"
- property string strEnter: "Enter"
- property string strClose: "keyboard_hide"
-
- property var modelKeyboard: {
- "row_1": [{
- "text": 'q',
- "symbol": '1',
- "width": 1
- }, {
- "text": 'w',
- "symbol": '2',
- "width": 1
- }, {
- "text": 'e',
- "symbol": '3',
- "width": 1
- }, {
- "text": 'r',
- "symbol": '4',
- "width": 1
- }, {
- "text": 't',
- "symbol": '5',
- "width": 1
- }, {
- "text": 'y',
- "symbol": '6',
- "width": 1
- }, {
- "text": 'u',
- "symbol": '7',
- "width": 1
- }, {
- "text": 'i',
- "symbol": '8',
- "width": 1
- }, {
- "text": 'o',
- "symbol": '9',
- "width": 1
- }, {
- "text": 'p',
- "symbol": '0',
- "width": 1
- }],
- "row_2": [{
- "text": 'a',
- "symbol": '-',
- "width": 1
- }, {
- "text": 's',
- "symbol": '/',
- "width": 1
- }, {
- "text": 'd',
- "symbol": ':',
- "width": 1
- }, {
- "text": 'f',
- "symbol": ';',
- "width": 1
- }, {
- "text": 'g',
- "symbol": '(',
- "width": 1
- }, {
- "text": 'h',
- "symbol": ')',
- "width": 1
- }, {
- "text": 'j',
- "symbol": '€',
- "width": 1
- }, {
- "text": 'k',
- "symbol": '&',
- "width": 1
- }, {
- "text": 'l',
- "symbol": '@',
- "width": 1
- }],
- "row_3": [{
- "text": strShift,
- "symbol": strShift,
- "width": 1.5
- }, {
- "text": 'z',
- "symbol": '.',
- "width": 1
- }, {
- "text": 'x',
- "symbol": ',',
- "width": 1
- }, {
- "text": 'c',
- "symbol": '?',
- "width": 1
- }, {
- "text": 'v',
- "symbol": '!',
- "width": 1
- }, {
- "text": 'b',
- "symbol": "'",
- "width": 1
- }, {
- "text": 'n',
- "symbol": "%",
- "width": 1
- }, {
- "text": 'm',
- "symbol": '"',
- "width": 1
- }, {
- "text": strBackspace,
- "symbol": strBackspace,
- "width": 1.5
- }],
- "row_4": [{
- "text": strClose,
- "symbol": strClose,
- "width": 1.5
- }, {
- "text": "123",
- "symbol": 'ABC',
- "width": 1.5
- }, {
- "text": ' ',
- "symbol": ' ',
- "width": 4.5
- }, {
- "text": '.',
- "symbol": '.',
- "width": 1
- }, {
- "text": strEnter,
- "symbol": strEnter,
- "width": 1.5
- }]
- }
-
- //Here is the corresponding table between the ascii and the key event
- property var tableKeyEvent: {
- "_0": Qt.Key_0,
- "_1": Qt.Key_1,
- "_2": Qt.Key_2,
- "_3": Qt.Key_3,
- "_4": Qt.Key_4,
- "_5": Qt.Key_5,
- "_6": Qt.Key_6,
- "_7": Qt.Key_7,
- "_8": Qt.Key_8,
- "_9": Qt.Key_9,
- "_a": Qt.Key_A,
- "_b": Qt.Key_B,
- "_c": Qt.Key_C,
- "_d": Qt.Key_D,
- "_e": Qt.Key_E,
- "_f": Qt.Key_F,
- "_g": Qt.Key_G,
- "_h": Qt.Key_H,
- "_i": Qt.Key_I,
- "_j": Qt.Key_J,
- "_k": Qt.Key_K,
- "_l": Qt.Key_L,
- "_m": Qt.Key_M,
- "_n": Qt.Key_N,
- "_o": Qt.Key_O,
- "_p": Qt.Key_P,
- "_q": Qt.Key_Q,
- "_r": Qt.Key_R,
- "_s": Qt.Key_S,
- "_t": Qt.Key_T,
- "_u": Qt.Key_U,
- "_v": Qt.Key_V,
- "_w": Qt.Key_W,
- "_x": Qt.Key_X,
- "_y": Qt.Key_Y,
- "_z": Qt.Key_Z,
- "_←": Qt.Key_Backspace,
- "_return": Qt.Key_Return,
- "_ ": Qt.Key_Space,
- "_-": Qt.Key_Minus,
- "_/": Qt.Key_Slash,
- "_:": Qt.Key_Colon,
- "_;": Qt.Key_Semicolon,
- "_(": Qt.Key_BracketLeft,
- "_)": Qt.Key_BracketRight,
- "_€": parseInt(
- "20ac",
- 16) // I didn't find the appropriate Qt event so I used the hex format
- ,
- "_&": Qt.Key_Ampersand,
- "_@": Qt.Key_At,
- '_"': Qt.Key_QuoteDbl,
- "_.": Qt.Key_Period,
- "_,": Qt.Key_Comma,
- "_?": Qt.Key_Question,
- "_!": Qt.Key_Exclam,
- "_'": Qt.Key_Apostrophe,
- "_%": Qt.Key_Percent,
- "_*": Qt.Key_Asterisk
-}
-
-Item {
-id: keyboard_container
-anchors.left: parent.left
-anchors.leftMargin: 5
-anchors.right: parent.right
-anchors.top: parent.top
-anchors.topMargin: 5
-anchors.bottom: parent.bottom
-anchors.bottomMargin: 5
-
-//One column which contains 5 rows
-Column {
-spacing: columnSpacing
-
-Row {
-id: row_1
-spacing: rowSpacing
-Repeater {
-model: modelKeyboard["row_1"]
-delegate: CustomButtonKeyboard {
-text: symbols ? modelData.symbol : shift ? modelData.text.toUpperCase
-() : modelData.text
-width: modelData.width * keyboard_container.width / columns - rowSpacing
-height: keyboard_container.height / rows - columnSpacing
-
-onClicked: root.clicked(text)
-}
-}
-}
-Row {
-id: row_2
-spacing: rowSpacing
-Repeater {
-model: modelKeyboard["row_2"]
-delegate: CustomButtonKeyboard {
-text: symbols ? modelData.symbol : shift ? modelData.text.toUpperCase
-() : modelData.text
-width: modelData.width * keyboard_container.width / columns - rowSpacing
-height: keyboard_container.height / rows - columnSpacing
-
-onClicked: root.clicked(text)
-}
-}
-}
-Row {
-id: row_3
-spacing: rowSpacing
-Repeater {
-model: modelKeyboard["row_3"]
-delegate: CustomButtonKeyboard {
-text: symbols ? modelData.symbol : shift ? modelData.text.toUpperCase
-() : modelData.text
-width: modelData.width * keyboard_container.width / columns - rowSpacing
-height: keyboard_container.height / rows - columnSpacing
-isShift: shift && text === strShift
-
-onClicked: root.clicked(text)
-}
-}
-}
-Row {
-id: row_4
-spacing: rowSpacing
-Repeater {
-model: modelKeyboard["row_4"]
-delegate: CustomButtonKeyboard {
-text: symbols ? modelData.symbol : shift ? modelData.text.toUpperCase
-() : modelData.text
-width: modelData.width * keyboard_container.width / columns - rowSpacing
-height: keyboard_container.height / rows - columnSpacing
-
-onClicked: root.clicked(text)
-}
-}
-}
-}
-}
-signal clicked(string text)
-
-Connections {
-target: root
-function onClicked(text) {
-if (!keyboard_controller.target)
-return
-if (text === strShift) {
-root.shift = !root.shift
-} else if (text === '123') {
-root.symbols = true
-} else if (text === 'ABC') {
-root.symbols = false
-} else if (text === strEnter) {
-if (keyboard_controller.target.accepted) {
-keyboard_controller.target.accepted()
-}
-} else if (text === strClose) {
-root.dismissed()
-} else {
-if (text === strBackspace) {
-var current = keyboard_controller.target.text
-keyboard_controller.target.text = current.slice(0, current.length - 1)
-} else {
-var charToInsert = root.symbols ? text : (root.shift ? text.toUpperCase
-() : text)
-var current = keyboard_controller.target.text
-var cursorPos = keyboard_controller.target.cursorPosition
-keyboard_controller.target.text = current.slice(0,
-cursorPos) + charToInsert + current.slice(cursorPos)
-keyboard_controller.target.cursorPosition = cursorPos + 1
-}
-
-if (root.shift && text !== strShift)
-root.shift = false
-}
-}
-}
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/KeyboardController.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/KeyboardController.qml
deleted file mode 100644
index 09d77a5..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/KeyboardController.qml
+++ /dev/null
@@ -1,40 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-
-Item {
- id: keyboard_controller
-
- // reference on the TextInput
- property Item target
- //Booléan on the state of the keyboard
- property bool isKeyboardActive: false
-
- property var rootObject
-
- function show() {
- if (!isKeyboardActive && keyboard === null) {
- keyboard = keyboardComponent.createObject(
- keyboard_controller.rootObject)
- keyboard.target = keyboard_controller.target
- keyboard.dismissed.connect(hide)
- isKeyboardActive = true
- } else
- console.log("The keyboard is already shown")
- }
-
- function hide() {
- if (isKeyboardActive && keyboard !== null) {
- keyboard.destroy()
- isKeyboardActive = false
- } else
- console.log("The keyboard is already hidden")
- }
-
- // private
- property Item keyboard: null
- Component {
- id: keyboardComponent
- Keyboard {}
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Lock.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Lock.qml
deleted file mode 100644
index 9a5a00f..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Lock.qml
+++ /dev/null
@@ -1,296 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import Quickshell.Wayland
-import qs.Common
-import qs.Services
-
-Scope {
- id: root
-
- property string sharedPasswordBuffer: ""
- property bool shouldLock: false
-
- onShouldLockChanged: {
- IdleService.isShellLocked = shouldLock;
- if (shouldLock && lockPowerOffArmed) {
- lockStateCheck.restart();
- }
- }
-
- Timer {
- id: lockStateCheck
- interval: 100
- repeat: false
- onTriggered: {
- if (sessionLock.locked && lockPowerOffArmed) {
- pendingLock = false;
- IdleService.monitorsOff = true;
- CompositorService.powerOffMonitors();
- lockWakeAllowed = false;
- lockWakeDebounce.restart();
- lockPowerOffArmed = false;
- dpmsReapplyTimer.start();
- }
- }
- }
-
- property bool lockInitiatedLocally: false
- property bool pendingLock: false
- property bool lockPowerOffArmed: false
- property bool lockWakeAllowed: false
-
- Component.onCompleted: {
- IdleService.lockComponent = this;
- if (SettingsData.lockAtStartup)
- lock();
- }
-
- function notifyLoginctl(lockAction: bool) {
- if (!SettingsData.loginctlLockIntegration || !DMSService.isConnected)
- return;
- if (lockAction)
- DMSService.lockSession(() => {});
- else
- DMSService.unlockSession(() => {});
- }
-
- function lock() {
- if (SettingsData.customPowerActionLock?.length > 0) {
- Quickshell.execDetached(["sh", "-c", SettingsData.customPowerActionLock]);
- return;
- }
- if (shouldLock || pendingLock)
- return;
-
- lockInitiatedLocally = true;
- lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
-
- if (!SessionService.active && SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration) {
- pendingLock = true;
- notifyLoginctl(true);
- return;
- }
-
- shouldLock = true;
- notifyLoginctl(true);
- }
-
- function unlock() {
- if (!shouldLock)
- return;
- lockInitiatedLocally = false;
- notifyLoginctl(false);
- shouldLock = false;
- }
-
- function forceReset() {
- lockInitiatedLocally = false;
- pendingLock = false;
- shouldLock = false;
- }
-
- function activate() {
- lock();
- }
-
- Connections {
- target: SessionService
-
- function onSessionLocked() {
- if (shouldLock || pendingLock)
- return;
- if (!SessionService.active && SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration) {
- pendingLock = true;
- lockInitiatedLocally = false;
- return;
- }
- lockInitiatedLocally = false;
- lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
- shouldLock = true;
- }
-
- function onSessionUnlocked() {
- if (pendingLock) {
- pendingLock = false;
- lockInitiatedLocally = false;
- return;
- }
- if (!shouldLock || lockInitiatedLocally)
- return;
- shouldLock = false;
- }
-
- function onLoginctlStateChanged() {
- if (SessionService.active && pendingLock) {
- pendingLock = false;
- lockInitiatedLocally = true;
- lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
- shouldLock = true;
- return;
- }
- if (SessionService.locked && !shouldLock && !pendingLock) {
- lockInitiatedLocally = false;
- lockPowerOffArmed = SettingsData.lockScreenPowerOffMonitorsOnLock;
- shouldLock = true;
- }
- }
- }
-
- Connections {
- target: IdleService
-
- function onLockRequested() {
- lock();
- }
- }
-
- WlSessionLock {
- id: sessionLock
-
- locked: shouldLock
-
- WlSessionLockSurface {
- id: lockSurface
-
- property string currentScreenName: screen?.name ?? ""
- property bool isActiveScreen: {
- if (Quickshell.screens.length <= 1)
- return true;
- if (SettingsData.lockScreenActiveMonitor === "all")
- return true;
- return currentScreenName === SettingsData.lockScreenActiveMonitor;
- }
-
- color: isActiveScreen ? "transparent" : SettingsData.lockScreenInactiveColor
-
- LockSurface {
- anchors.fill: parent
- visible: lockSurface.isActiveScreen
- lock: sessionLock
- sharedPasswordBuffer: root.sharedPasswordBuffer
- screenName: lockSurface.currentScreenName
- isLocked: shouldLock
- onUnlockRequested: root.unlock()
- onPasswordChanged: newPassword => {
- root.sharedPasswordBuffer = newPassword;
- }
- }
- }
- }
-
- Connections {
- target: sessionLock
-
- function onLockedChanged() {
- if (sessionLock.locked) {
- pendingLock = false;
- if (lockPowerOffArmed && SettingsData.lockScreenPowerOffMonitorsOnLock) {
- IdleService.monitorsOff = true;
- CompositorService.powerOffMonitors();
- lockWakeAllowed = false;
- lockWakeDebounce.restart();
- }
- lockPowerOffArmed = false;
- dpmsReapplyTimer.start();
- return;
- }
-
- lockWakeAllowed = false;
- if (IdleService.monitorsOff && SettingsData.lockScreenPowerOffMonitorsOnLock) {
- IdleService.monitorsOff = false;
- CompositorService.powerOnMonitors();
- }
- }
- }
-
- LockScreenDemo {
- id: demoWindow
- }
-
- IpcHandler {
- target: "lock"
-
- function lock() {
- root.lock();
- }
-
- function unlock() {
- root.unlock();
- }
-
- function forceReset() {
- root.forceReset();
- }
-
- function demo() {
- demoWindow.showDemo();
- }
-
- function isLocked(): bool {
- return sessionLock.locked;
- }
-
- function status(): string {
- return JSON.stringify({
- shouldLock: root.shouldLock,
- sessionLockLocked: sessionLock.locked,
- lockInitiatedLocally: root.lockInitiatedLocally,
- pendingLock: root.pendingLock,
- loginctlLocked: SessionService.locked,
- loginctlActive: SessionService.active
- });
- }
- }
-
- Timer {
- id: dpmsReapplyTimer
- interval: 100
- repeat: false
- onTriggered: IdleService.reapplyDpmsIfNeeded()
- }
-
- Timer {
- id: lockWakeDebounce
- interval: 200
- repeat: false
- onTriggered: {
- if (!sessionLock.locked)
- return;
- if (!SettingsData.lockScreenPowerOffMonitorsOnLock)
- return;
- if (!IdleService.monitorsOff) {
- lockWakeAllowed = true;
- return;
- }
- if (lockWakeAllowed) {
- IdleService.monitorsOff = false;
- CompositorService.powerOnMonitors();
- } else {
- lockWakeAllowed = true;
- }
- }
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: sessionLock.locked
- hoverEnabled: enabled
- onPressed: lockWakeDebounce.restart()
- onPositionChanged: lockWakeDebounce.restart()
- onWheel: lockWakeDebounce.restart()
- }
-
- FocusScope {
- anchors.fill: parent
- focus: sessionLock.locked
-
- Keys.onPressed: event => {
- if (!sessionLock.locked)
- return;
- lockWakeDebounce.restart();
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockPowerMenu.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockPowerMenu.qml
deleted file mode 100644
index 0a0ee84..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockPowerMenu.qml
+++ /dev/null
@@ -1,820 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import QtQuick.Effects
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Rectangle {
- id: root
-
- property bool isVisible: false
- property bool showLogout: true
- property int selectedIndex: 0
- property int selectedRow: 0
- property int selectedCol: 0
- property var visibleActions: []
- property int gridColumns: 3
- property int gridRows: 2
- property bool useGridLayout: false
-
- property string holdAction: ""
- property int holdActionIndex: -1
- property real holdProgress: 0
- property bool showHoldHint: false
-
- property var powerActionConfirmOverride: undefined
- property var powerActionHoldDurationOverride: undefined
- property var powerMenuActionsOverride: undefined
- property var powerMenuDefaultActionOverride: undefined
- property var powerMenuGridLayoutOverride: undefined
- property var requiredActions: []
-
- readonly property bool needsConfirmation: powerActionConfirmOverride !== undefined ? powerActionConfirmOverride : SettingsData.powerActionConfirm
- readonly property int holdDurationMs: (powerActionHoldDurationOverride !== undefined ? powerActionHoldDurationOverride : SettingsData.powerActionHoldDuration) * 1000
-
- signal closed
-
- function updateVisibleActions() {
- const allActions = powerMenuActionsOverride !== undefined ? powerMenuActionsOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuActions) ? SettingsData.powerMenuActions : ["logout", "suspend", "hibernate", "reboot", "poweroff"]);
- const hibernateSupported = (typeof SessionService !== "undefined" && SessionService.hibernateSupported) || false;
- let filtered = allActions.filter(action => {
- if (action === "hibernate" && !hibernateSupported)
- return false;
- if (action === "lock")
- return false;
- if (action === "restart")
- return false;
- if (action === "logout" && !showLogout)
- return false;
- return true;
- });
-
- for (const action of requiredActions) {
- if (!filtered.includes(action))
- filtered.push(action);
- }
-
- visibleActions = filtered;
-
- useGridLayout = powerMenuGridLayoutOverride !== undefined ? powerMenuGridLayoutOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined) ? SettingsData.powerMenuGridLayout : false);
- if (!useGridLayout)
- return;
- const count = visibleActions.length;
- if (count === 0) {
- gridColumns = 1;
- gridRows = 1;
- return;
- }
-
- if (count <= 3) {
- gridColumns = 1;
- gridRows = count;
- return;
- }
-
- if (count === 4) {
- gridColumns = 2;
- gridRows = 2;
- return;
- }
-
- gridColumns = 3;
- gridRows = Math.ceil(count / 3);
- }
-
- function getDefaultActionIndex() {
- const defaultAction = powerMenuDefaultActionOverride !== undefined ? powerMenuDefaultActionOverride : ((typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction) ? SettingsData.powerMenuDefaultAction : "suspend");
- const index = visibleActions.indexOf(defaultAction);
- return index >= 0 ? index : 0;
- }
-
- function getActionAtIndex(index) {
- if (index < 0 || index >= visibleActions.length)
- return "";
- return visibleActions[index];
- }
-
- function getActionData(action) {
- switch (action) {
- case "reboot":
- return {
- "icon": "restart_alt",
- "label": I18n.tr("Reboot"),
- "key": "R"
- };
- case "logout":
- return {
- "icon": "logout",
- "label": I18n.tr("Log Out"),
- "key": "X"
- };
- case "poweroff":
- return {
- "icon": "power_settings_new",
- "label": I18n.tr("Power Off"),
- "key": "P"
- };
- case "suspend":
- return {
- "icon": "bedtime",
- "label": I18n.tr("Suspend"),
- "key": "S"
- };
- case "hibernate":
- return {
- "icon": "ac_unit",
- "label": I18n.tr("Hibernate"),
- "key": "H"
- };
- default:
- return {
- "icon": "help",
- "label": action,
- "key": "?"
- };
- }
- }
-
- function actionNeedsConfirm(action) {
- return action !== "lock" && action !== "restart";
- }
-
- function startHold(action, actionIndex) {
- if (!needsConfirmation || !actionNeedsConfirm(action)) {
- executeAction(action);
- return;
- }
- holdAction = action;
- holdActionIndex = actionIndex;
- holdProgress = 0;
- showHoldHint = false;
- holdTimer.start();
- }
-
- function cancelHold() {
- if (holdAction === "")
- return;
- const wasHolding = holdProgress > 0;
- holdTimer.stop();
- if (wasHolding && holdProgress < 1) {
- showHoldHint = true;
- hintTimer.restart();
- }
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- }
-
- function completeHold() {
- if (holdProgress < 1) {
- cancelHold();
- return;
- }
- const action = holdAction;
- holdTimer.stop();
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- executeAction(action);
- }
-
- function executeAction(action) {
- if (!action)
- return;
- if (typeof SessionService === "undefined")
- return;
- hide();
- switch (action) {
- case "logout":
- SessionService.logout();
- break;
- case "suspend":
- SessionService.suspend();
- break;
- case "hibernate":
- SessionService.hibernate();
- break;
- case "reboot":
- SessionService.reboot();
- break;
- case "poweroff":
- SessionService.poweroff();
- break;
- }
- }
-
- function selectOption(action, actionIndex) {
- startHold(action, actionIndex !== undefined ? actionIndex : -1);
- }
-
- function show() {
- holdAction = "";
- holdActionIndex = -1;
- holdProgress = 0;
- showHoldHint = false;
- updateVisibleActions();
- const defaultIndex = getDefaultActionIndex();
- if (useGridLayout) {
- selectedRow = Math.floor(defaultIndex / gridColumns);
- selectedCol = defaultIndex % gridColumns;
- selectedIndex = defaultIndex;
- } else {
- selectedIndex = defaultIndex;
- }
- isVisible = true;
- Qt.callLater(() => powerMenuFocusScope.forceActiveFocus());
- }
-
- function hide() {
- cancelHold();
- isVisible = false;
- closed();
- }
-
- function handleListNavigation(event, isPressed) {
- if (!isPressed) {
- if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_S || event.key === Qt.Key_H || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) {
- cancelHold();
- event.accepted = true;
- }
- return;
- }
-
- switch (event.key) {
- case Qt.Key_Up:
- case Qt.Key_Backtab:
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- break;
- case Qt.Key_Down:
- case Qt.Key_Tab:
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- startHold(getActionAtIndex(selectedIndex), selectedIndex);
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (!(event.modifiers & Qt.ControlModifier)) {
- const idx = visibleActions.indexOf("poweroff");
- startHold("poweroff", idx);
- event.accepted = true;
- } else {
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex + 1) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length;
- event.accepted = true;
- }
- break;
- case Qt.Key_R:
- startHold("reboot", visibleActions.indexOf("reboot"));
- event.accepted = true;
- break;
- case Qt.Key_X:
- startHold("logout", visibleActions.indexOf("logout"));
- event.accepted = true;
- break;
- case Qt.Key_S:
- startHold("suspend", visibleActions.indexOf("suspend"));
- event.accepted = true;
- break;
- case Qt.Key_H:
- startHold("hibernate", visibleActions.indexOf("hibernate"));
- event.accepted = true;
- break;
- }
- }
-
- function handleGridNavigation(event, isPressed) {
- if (!isPressed) {
- if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_R || event.key === Qt.Key_X || event.key === Qt.Key_S || event.key === Qt.Key_H || (event.key === Qt.Key_P && !(event.modifiers & Qt.ControlModifier))) {
- cancelHold();
- event.accepted = true;
- }
- return;
- }
-
- switch (event.key) {
- case Qt.Key_Left:
- selectedCol = (selectedCol - 1 + gridColumns) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Right:
- selectedCol = (selectedCol + 1) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Up:
- case Qt.Key_Backtab:
- selectedRow = (selectedRow - 1 + gridRows) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Down:
- case Qt.Key_Tab:
- selectedRow = (selectedRow + 1) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- break;
- case Qt.Key_Return:
- case Qt.Key_Enter:
- startHold(getActionAtIndex(selectedIndex), selectedIndex);
- event.accepted = true;
- break;
- case Qt.Key_N:
- if (event.modifiers & Qt.ControlModifier) {
- selectedCol = (selectedCol + 1) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_P:
- if (!(event.modifiers & Qt.ControlModifier)) {
- const idx = visibleActions.indexOf("poweroff");
- startHold("poweroff", idx);
- event.accepted = true;
- } else {
- selectedCol = (selectedCol - 1 + gridColumns) % gridColumns;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_J:
- if (event.modifiers & Qt.ControlModifier) {
- selectedRow = (selectedRow + 1) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_K:
- if (event.modifiers & Qt.ControlModifier) {
- selectedRow = (selectedRow - 1 + gridRows) % gridRows;
- selectedIndex = selectedRow * gridColumns + selectedCol;
- event.accepted = true;
- }
- break;
- case Qt.Key_R:
- startHold("reboot", visibleActions.indexOf("reboot"));
- event.accepted = true;
- break;
- case Qt.Key_X:
- startHold("logout", visibleActions.indexOf("logout"));
- event.accepted = true;
- break;
- case Qt.Key_S:
- startHold("suspend", visibleActions.indexOf("suspend"));
- event.accepted = true;
- break;
- case Qt.Key_H:
- startHold("hibernate", visibleActions.indexOf("hibernate"));
- event.accepted = true;
- break;
- }
- }
-
- anchors.fill: parent
- color: Qt.rgba(0, 0, 0, 0.5)
- visible: isVisible
- z: 1000
-
- MouseArea {
- anchors.fill: parent
- onClicked: root.hide()
- }
-
- Timer {
- id: holdTimer
- interval: 16
- repeat: true
- onTriggered: {
- root.holdProgress = Math.min(1, root.holdProgress + (interval / root.holdDurationMs));
- if (root.holdProgress >= 1) {
- stop();
- root.completeHold();
- }
- }
- }
-
- Timer {
- id: hintTimer
- interval: 2000
- onTriggered: root.showHoldHint = false
- }
-
- FocusScope {
- id: powerMenuFocusScope
- anchors.fill: parent
- focus: root.isVisible
-
- onVisibleChanged: {
- if (visible)
- Qt.callLater(() => forceActiveFocus());
- }
-
- Keys.onEscapePressed: root.hide()
- Keys.onPressed: event => {
- if (event.isAutoRepeat) {
- event.accepted = true;
- return;
- }
- if (useGridLayout) {
- handleGridNavigation(event, true);
- } else {
- handleListNavigation(event, true);
- }
- }
- Keys.onReleased: event => {
- if (event.isAutoRepeat) {
- event.accepted = true;
- return;
- }
- if (useGridLayout) {
- handleGridNavigation(event, false);
- } else {
- handleListNavigation(event, false);
- }
- }
-
- Rectangle {
- anchors.centerIn: parent
- width: useGridLayout ? Math.min(550, gridColumns * 180 + Theme.spacingS * (gridColumns - 1) + Theme.spacingL * 2) : 320
- height: contentItem.implicitHeight + Theme.spacingL * 2
- radius: Theme.cornerRadius
- color: Theme.surfaceContainer
- border.color: Theme.outlineMedium
- border.width: 1
-
- Item {
- id: contentItem
- anchors.fill: parent
- anchors.margins: Theme.spacingL
- implicitHeight: headerRow.height + Theme.spacingM + (useGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight) + (root.needsConfirmation ? hintRow.height + Theme.spacingM : 0)
-
- Row {
- id: headerRow
- width: parent.width
- height: 30
-
- StyledText {
- text: I18n.tr("Power Options")
- font.pixelSize: Theme.fontSizeLarge
- color: Theme.surfaceText
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Item {
- width: parent.width - 150
- height: 1
- }
-
- DankActionButton {
- iconName: "close"
- iconSize: Theme.iconSize - 4
- iconColor: Theme.surfaceText
- onClicked: root.hide()
- }
- }
-
- Grid {
- id: buttonGrid
- visible: useGridLayout
- anchors.top: headerRow.bottom
- anchors.topMargin: Theme.spacingM
- anchors.horizontalCenter: parent.horizontalCenter
- columns: root.gridColumns
- columnSpacing: Theme.spacingS
- rowSpacing: Theme.spacingS
- width: parent.width
-
- Repeater {
- model: root.visibleActions
-
- Rectangle {
- id: gridButtonRect
- required property int index
- required property string modelData
-
- readonly property var actionData: root.getActionData(modelData)
- readonly property bool isSelected: root.selectedIndex === index
- readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
- readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0
-
- width: (contentItem.width - Theme.spacingS * (root.gridColumns - 1)) / root.gridColumns
- height: 100
- radius: Theme.cornerRadius
- color: {
- if (isSelected)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- if (mouseArea.containsMouse)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
- return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
- }
- border.color: isSelected ? Theme.primary : "transparent"
- border.width: isSelected ? 2 : 0
-
- Rectangle {
- id: gridProgressMask
- anchors.fill: parent
- radius: parent.radius
- visible: false
- layer.enabled: true
- }
-
- Item {
- anchors.fill: parent
- visible: gridButtonRect.isHolding
- layer.enabled: gridButtonRect.isHolding
- layer.effect: MultiEffect {
- maskEnabled: true
- maskSource: gridProgressMask
- maskSpreadAtMin: 1
- maskThresholdMin: 0.5
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * root.holdProgress
- color: {
- if (gridButtonRect.modelData === "poweroff")
- return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3);
- if (gridButtonRect.modelData === "reboot")
- return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3);
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
- }
- }
- }
-
- Column {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- DankIcon {
- name: gridButtonRect.actionData.icon
- size: Theme.iconSize + 8
- color: {
- if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) {
- return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- StyledText {
- text: gridButtonRect.actionData.label
- font.pixelSize: Theme.fontSizeMedium
- color: {
- if (gridButtonRect.showWarning && (mouseArea.containsMouse || gridButtonRect.isHolding)) {
- return gridButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- font.weight: Font.Medium
- anchors.horizontalCenter: parent.horizontalCenter
- }
-
- Rectangle {
- width: 20
- height: 16
- radius: 4
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
- anchors.horizontalCenter: parent.horizontalCenter
-
- StyledText {
- text: gridButtonRect.actionData.key
- font.pixelSize: Theme.fontSizeSmall - 1
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: {
- root.selectedRow = Math.floor(index / root.gridColumns);
- root.selectedCol = index % root.gridColumns;
- root.selectedIndex = index;
- root.startHold(modelData, index);
- }
- onReleased: root.cancelHold()
- onCanceled: root.cancelHold()
- }
- }
- }
- }
-
- Column {
- id: buttonColumn
- visible: !useGridLayout
- anchors.top: headerRow.bottom
- anchors.topMargin: Theme.spacingM
- anchors.left: parent.left
- anchors.right: parent.right
- spacing: Theme.spacingS
-
- Repeater {
- model: root.visibleActions
-
- Rectangle {
- id: listButtonRect
- required property int index
- required property string modelData
-
- readonly property var actionData: root.getActionData(modelData)
- readonly property bool isSelected: root.selectedIndex === index
- readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
- readonly property bool isHolding: root.holdActionIndex === index && root.holdProgress > 0
-
- width: parent.width
- height: 50
- radius: Theme.cornerRadius
- color: {
- if (isSelected)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12);
- if (listMouseArea.containsMouse)
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08);
- return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08);
- }
- border.color: isSelected ? Theme.primary : "transparent"
- border.width: isSelected ? 2 : 0
-
- Rectangle {
- id: listProgressMask
- anchors.fill: parent
- radius: parent.radius
- visible: false
- layer.enabled: true
- }
-
- Item {
- anchors.fill: parent
- visible: listButtonRect.isHolding
- layer.enabled: listButtonRect.isHolding
- layer.effect: MultiEffect {
- maskEnabled: true
- maskSource: listProgressMask
- maskSpreadAtMin: 1
- maskThresholdMin: 0.5
- }
-
- Rectangle {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * root.holdProgress
- color: {
- if (listButtonRect.modelData === "poweroff")
- return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3);
- if (listButtonRect.modelData === "reboot")
- return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.3);
- return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3);
- }
- }
- }
-
- Row {
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.leftMargin: Theme.spacingM
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- spacing: Theme.spacingM
-
- DankIcon {
- name: listButtonRect.actionData.icon
- size: Theme.iconSize + 4
- color: {
- if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) {
- return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: listButtonRect.actionData.label
- font.pixelSize: Theme.fontSizeMedium
- color: {
- if (listButtonRect.showWarning && (listMouseArea.containsMouse || listButtonRect.isHolding)) {
- return listButtonRect.modelData === "poweroff" ? Theme.error : Theme.warning;
- }
- return Theme.surfaceText;
- }
- font.weight: Font.Medium
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- width: 28
- height: 20
- radius: 4
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
- anchors.right: parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- text: listButtonRect.actionData.key
- font.pixelSize: Theme.fontSizeSmall
- color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- font.weight: Font.Medium
- anchors.centerIn: parent
- }
- }
-
- MouseArea {
- id: listMouseArea
- anchors.fill: parent
- hoverEnabled: true
- cursorShape: Qt.PointingHandCursor
- onPressed: {
- root.selectedIndex = index;
- root.startHold(modelData, index);
- }
- onReleased: root.cancelHold()
- onCanceled: root.cancelHold()
- }
- }
- }
- }
-
- Row {
- id: hintRow
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- anchors.bottomMargin: Theme.spacingS
- spacing: Theme.spacingXS
- visible: root.needsConfirmation
- opacity: root.showHoldHint ? 1 : 0.5
-
- Behavior on opacity {
- NumberAnimation {
- duration: 150
- }
- }
-
- DankIcon {
- name: root.showHoldHint ? "warning" : "touch_app"
- size: Theme.fontSizeSmall
- color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- readonly property real totalMs: root.holdDurationMs
- readonly property int remainingMs: Math.ceil(totalMs * (1 - root.holdProgress))
- readonly property real durationSec: root.holdDurationMs / 1000
- text: {
- if (root.showHoldHint)
- return I18n.tr("Hold longer to confirm");
- if (root.holdProgress > 0) {
- if (totalMs < 1000)
- return I18n.tr("Hold to confirm (%1 ms)").arg(remainingMs);
- return I18n.tr("Hold to confirm (%1s)").arg(Math.ceil(remainingMs / 1000));
- }
- if (totalMs < 1000)
- return I18n.tr("Hold to confirm (%1 ms)").arg(totalMs);
- return I18n.tr("Hold to confirm (%1s)").arg(durationSec);
- }
- font.pixelSize: Theme.fontSizeSmall
- color: root.showHoldHint ? Theme.warning : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
- }
- }
-
- Component.onCompleted: updateVisibleActions()
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenContent.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenContent.qml
deleted file mode 100644
index b296e98..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenContent.qml
+++ /dev/null
@@ -1,1707 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import QtQuick.Effects
-import QtQuick.Layouts
-import QtQuick.Window
-import Quickshell
-import Quickshell.Hyprland
-import Quickshell.Io
-import Quickshell.Services.Mpris
-import qs.Common
-import qs.Services
-import qs.Widgets
-
-Item {
- id: root
-
- function encodeFileUrl(path) {
- if (!path)
- return "";
- return "file://" + path.split('/').map(s => encodeURIComponent(s)).join('/');
- }
-
- property string passwordBuffer: ""
- property bool demoMode: false
- property string screenName: ""
- property bool unlocking: false
- property string pamState: ""
- property string hyprlandCurrentLayout: ""
- property string hyprlandKeyboard: ""
- property int hyprlandLayoutCount: 0
- property bool lockerReadySent: false
- property bool lockerReadyArmed: false
-
- signal unlockRequested
-
- function resetLockState() {
- lockerReadySent = false;
- lockerReadyArmed = true;
- unlocking = false;
- pamState = "";
- if (pam)
- pam.lockMessage = "";
- }
-
- function currentAuthFeedbackText() {
- if (!pam)
- return "";
- if (pam.u2fState === "insert" && !pam.u2fPending)
- return I18n.tr("Insert your security key...");
- if (pam.u2fState === "waiting" && !pam.u2fPending)
- return I18n.tr("Touch your security key...");
- if (pam.lockMessage && pam.lockMessage.length > 0)
- return pam.lockMessage;
- if (root.pamState === "error")
- return I18n.tr("Authentication error - try again");
- if (root.pamState === "max")
- return I18n.tr("Too many attempts - locked out");
- if (root.pamState === "fail")
- return I18n.tr("Incorrect password - try again");
- if (pam.fprintState === "error") {
- const detail = (pam.fprint.message || "").trim();
- return detail.length > 0 ? I18n.tr("Fingerprint error: %1").arg(detail) : I18n.tr("Fingerprint error");
- }
- if (pam.fprintState === "max")
- return I18n.tr("Maximum fingerprint attempts reached. Please use password.");
- if (pam.fprintState === "fail")
- return I18n.tr("Fingerprint not recognized (%1/%2). Please try again or use password.").arg(pam.fprint.tries).arg(SettingsData.maxFprintTries);
- return "";
- }
-
- function authFeedbackIsHint() {
- return pam && (pam.u2fState === "waiting" || pam.u2fState === "insert") && !pam.u2fPending;
- }
-
- Component.onCompleted: {
- WeatherService.addRef();
- UserInfoService.getUserInfo();
-
- if (CompositorService.isHyprland)
- updateHyprlandLayout();
-
- lockerReadyArmed = true;
- }
-
- Component.onDestruction: {
- WeatherService.removeRef();
- }
-
- function sendLockerReadyOnce() {
- if (lockerReadySent)
- return;
- if (root.unlocking)
- return;
- lockerReadySent = true;
- if (SessionService.loginctlAvailable && DMSService.apiVersion >= 2) {
- DMSService.sendRequest("loginctl.lockerReady", null, resp => {
- if (resp?.error)
- console.warn("lockerReady failed:", resp.error);
- else
- console.log("lockerReady sent (afterAnimating/afterRendering)");
- });
- }
- }
-
- function maybeSend() {
- if (!lockerReadyArmed)
- return;
- if (root.unlocking)
- return;
- if (!root.visible || root.opacity <= 0)
- return;
- Qt.callLater(() => {
- if (root.visible && root.opacity > 0 && !root.unlocking)
- sendLockerReadyOnce();
- });
- }
-
- Connections {
- target: root.Window.window
- enabled: target !== null
-
- function onAfterAnimating() {
- maybeSend();
- }
- function onAfterRendering() {
- maybeSend();
- }
- }
-
- onVisibleChanged: maybeSend()
- onOpacityChanged: maybeSend()
-
- function updateHyprlandLayout() {
- if (CompositorService.isHyprland) {
- hyprlandLayoutProcess.running = true;
- }
- }
-
- Process {
- id: hyprlandLayoutProcess
- running: false
- command: ["hyprctl", "-j", "devices"]
- stdout: StdioCollector {
- onStreamFinished: {
- try {
- const data = JSON.parse(text);
- const mainKeyboard = data.keyboards.find(kb => kb.main === true);
- if (!mainKeyboard) {
- hyprlandCurrentLayout = "";
- hyprlandLayoutCount = 0;
- return;
- }
- hyprlandKeyboard = mainKeyboard.name;
- if (mainKeyboard.active_keymap) {
- const parts = mainKeyboard.active_keymap.split(" ");
- hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase();
- } else {
- hyprlandCurrentLayout = "";
- }
- hyprlandLayoutCount = mainKeyboard.layout ? mainKeyboard.layout.split(",").length : 0;
- } catch (e) {
- hyprlandCurrentLayout = "";
- hyprlandLayoutCount = 0;
- }
- }
- }
- }
-
- Connections {
- target: CompositorService.isHyprland ? Hyprland : null
- enabled: CompositorService.isHyprland
-
- function onRawEvent(event) {
- if (event.name === "activelayout")
- updateHyprlandLayout();
- }
- }
-
- Loader {
- anchors.fill: parent
- active: {
- var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
- return !currentWallpaper || (currentWallpaper && currentWallpaper.startsWith("#"));
- }
- asynchronous: true
-
- sourceComponent: DankBackdrop {
- screenName: root.screenName
- }
- }
-
- Image {
- id: wallpaperBackground
-
- anchors.fill: parent
- source: {
- var currentWallpaper = SessionData.getMonitorWallpaper(screenName);
- return (currentWallpaper && !currentWallpaper.startsWith("#")) ? encodeFileUrl(currentWallpaper) : "";
- }
- fillMode: Theme.getFillMode(SessionData.getMonitorWallpaperFillMode(screenName))
- smooth: true
- asynchronous: false
- cache: true
- visible: source !== ""
- layer.enabled: true
-
- layer.effect: MultiEffect {
- autoPaddingEnabled: false
- blurEnabled: true
- blur: 0.8
- blurMax: 32
- blurMultiplier: 1
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- Rectangle {
- anchors.fill: parent
- color: "black"
- opacity: 0.4
- }
-
- SystemClock {
- id: systemClock
-
- precision: SystemClock.Seconds
- }
-
- Rectangle {
- anchors.fill: parent
- color: "transparent"
-
- Item {
- id: clockContainer
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.verticalCenter
- anchors.bottomMargin: 60
- width: parent.width
- height: clockText.implicitHeight
- visible: SettingsData.lockScreenShowTime
-
- Row {
- id: clockText
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- spacing: 0
-
- property string fullTimeStr: {
- const format = SettingsData.getEffectiveTimeFormat();
- return systemClock.date.toLocaleTimeString(Qt.locale(), format);
- }
- property var timeParts: fullTimeStr.split(':')
- property string hours: timeParts[0] || ""
- property string minutes: timeParts[1] || ""
- property string secondsWithAmPm: timeParts.length > 2 ? timeParts[2] : ""
- property string seconds: secondsWithAmPm.replace(/\s*(AM|PM|am|pm)$/i, '')
- property string ampm: {
- const match = fullTimeStr.match(/\s*(AM|PM|am|pm)$/i);
- return match ? match[0].trim() : "";
- }
- property bool hasSeconds: timeParts.length > 2
-
- StyledText {
- width: 75
- text: clockText.hours.length > 1 ? clockText.hours[0] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- }
-
- StyledText {
- width: 75
- text: clockText.hours.length > 1 ? clockText.hours[1] : clockText.hours.length > 0 ? clockText.hours[0] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- }
-
- StyledText {
- text: ":"
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- }
-
- StyledText {
- width: 75
- text: clockText.minutes.length > 0 ? clockText.minutes[0] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- }
-
- StyledText {
- width: 75
- text: clockText.minutes.length > 1 ? clockText.minutes[1] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- }
-
- StyledText {
- text: clockText.hasSeconds ? ":" : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- visible: clockText.hasSeconds
- }
-
- StyledText {
- width: 75
- text: clockText.hasSeconds && clockText.seconds.length > 0 ? clockText.seconds[0] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- visible: clockText.hasSeconds
- }
-
- StyledText {
- width: 75
- text: clockText.hasSeconds && clockText.seconds.length > 1 ? clockText.seconds[1] : ""
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- horizontalAlignment: Text.AlignHCenter
- visible: clockText.hasSeconds
- }
-
- StyledText {
- width: 20
- text: " "
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- visible: clockText.ampm !== ""
- }
-
- StyledText {
- text: clockText.ampm
- font.pixelSize: 120
- font.weight: Font.Light
- color: "white"
- visible: clockText.ampm !== ""
- }
- }
- }
-
- StyledText {
- id: dateText
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: clockContainer.bottom
- anchors.topMargin: 4
- visible: SettingsData.lockScreenShowDate
- text: {
- if (SettingsData.lockDateFormat && SettingsData.lockDateFormat.length > 0) {
- return systemClock.date.toLocaleDateString(I18n.locale(), SettingsData.lockDateFormat);
- }
- return systemClock.date.toLocaleDateString(I18n.locale(), Locale.LongFormat);
- }
- font.pixelSize: Theme.fontSizeXLarge
- color: "white"
- opacity: 0.9
- }
-
- Item {
- id: lockNotificationPanel
-
- readonly property int notificationMode: SettingsData.lockScreenNotificationMode
- readonly property var notifications: NotificationService.groupedNotifications
- readonly property int totalCount: {
- let count = 0;
- for (const group of notifications) {
- count += group.count || 0;
- }
- return count;
- }
- readonly property bool hasNotifications: totalCount > 0
- readonly property var appNameGroups: {
- const groups = {};
- for (const group of notifications) {
- const appName = (group.appName || "Unknown").toLowerCase();
- if (!groups[appName]) {
- groups[appName] = {
- appName: group.appName || I18n.tr("Unknown"),
- count: 0,
- latestNotification: group.latestNotification
- };
- }
- groups[appName].count += group.count || 0;
- if (group.latestNotification && (!groups[appName].latestNotification || group.latestNotification.time > groups[appName].latestNotification.time)) {
- groups[appName].latestNotification = group.latestNotification;
- }
- }
- return Object.values(groups).sort((a, b) => b.count - a.count);
- }
-
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: dateText.visible ? dateText.bottom : clockContainer.bottom
- anchors.topMargin: Theme.spacingM
- width: Math.min(380, parent.width - Theme.spacingXL * 2)
- height: notificationMode === 0 || !hasNotifications ? 0 : contentLoader.height
- visible: notificationMode > 0 && hasNotifications
- clip: true
-
- Behavior on height {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Loader {
- id: contentLoader
- anchors.left: parent.left
- anchors.right: parent.right
- active: lockNotificationPanel.notificationMode > 0 && lockNotificationPanel.hasNotifications
- sourceComponent: {
- switch (lockNotificationPanel.notificationMode) {
- case 1:
- return countOnlyComponent;
- case 2:
- return appNamesComponent;
- case 3:
- return fullContentComponent;
- default:
- return null;
- }
- }
- }
-
- Component {
- id: countOnlyComponent
-
- Rectangle {
- width: parent.width
- height: 44
- radius: Theme.cornerRadius
- color: Qt.rgba(0, 0, 0, 0.3)
- border.color: Qt.rgba(1, 1, 1, 0.1)
- border.width: 1
-
- Row {
- anchors.centerIn: parent
- spacing: Theme.spacingS
-
- DankIcon {
- name: "notifications"
- size: Theme.iconSize
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: lockNotificationPanel.totalCount === 1 ? I18n.tr("1 notification") : I18n.tr("%1 notifications").arg(lockNotificationPanel.totalCount)
- font.pixelSize: Theme.fontSizeMedium
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
- }
-
- Component {
- id: appNamesComponent
-
- Rectangle {
- width: parent.width
- height: Math.min(appNamesColumn.implicitHeight + Theme.spacingM * 2, 200)
- radius: Theme.cornerRadius
- color: Qt.rgba(0, 0, 0, 0.3)
- border.color: Qt.rgba(1, 1, 1, 0.1)
- border.width: 1
- clip: true
-
- Flickable {
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- contentHeight: appNamesColumn.implicitHeight
- clip: true
- boundsBehavior: Flickable.StopAtBounds
-
- Column {
- id: appNamesColumn
- width: parent.width
- spacing: Theme.spacingS
-
- Repeater {
- model: lockNotificationPanel.appNameGroups.slice(0, 5)
-
- Row {
- required property var modelData
- width: parent.width
- spacing: Theme.spacingS
-
- DankIcon {
- name: "notifications"
- size: Theme.iconSize - 4
- color: "white"
- opacity: 0.8
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: modelData.appName || I18n.tr("Unknown")
- font.pixelSize: Theme.fontSizeMedium
- color: "white"
- elide: Text.ElideRight
- width: parent.width - Theme.iconSize - countBadge.width - Theme.spacingS * 2
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Rectangle {
- id: countBadge
- width: countText.implicitWidth + Theme.spacingS * 2
- height: 20
- radius: 10
- color: Qt.rgba(1, 1, 1, 0.2)
- visible: modelData.count > 1
- anchors.verticalCenter: parent.verticalCenter
-
- StyledText {
- id: countText
- anchors.centerIn: parent
- text: modelData.count > 99 ? "99+" : modelData.count.toString()
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- }
- }
- }
- }
-
- StyledText {
- visible: lockNotificationPanel.appNameGroups.length > 5
- text: I18n.tr("+ %1 more").arg(lockNotificationPanel.appNameGroups.length - 5)
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- opacity: 0.7
- }
- }
- }
- }
- }
-
- Component {
- id: fullContentComponent
-
- Rectangle {
- width: parent.width
- height: Math.min(fullContentColumn.implicitHeight + Theme.spacingM * 2, 280)
- radius: Theme.cornerRadius
- color: Qt.rgba(0, 0, 0, 0.3)
- border.color: Qt.rgba(1, 1, 1, 0.1)
- border.width: 1
- clip: true
-
- Flickable {
- anchors.fill: parent
- anchors.margins: Theme.spacingM
- contentHeight: fullContentColumn.implicitHeight
- clip: true
- boundsBehavior: Flickable.StopAtBounds
-
- Column {
- id: fullContentColumn
- width: parent.width
- spacing: Theme.spacingM
-
- Repeater {
- model: {
- const items = [];
- for (const group of lockNotificationPanel.appNameGroups) {
- if (group.latestNotification && items.length < 5) {
- items.push(group.latestNotification);
- }
- }
- return items;
- }
-
- Rectangle {
- required property var modelData
- required property int index
- width: parent.width
- height: notifContent.implicitHeight + Theme.spacingS * 2
- radius: Theme.cornerRadius - 4
- color: Qt.rgba(1, 1, 1, 0.05)
-
- Column {
- id: notifContent
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: parent.top
- anchors.margins: Theme.spacingS
- spacing: 2
-
- Row {
- width: parent.width
- spacing: Theme.spacingXS
-
- StyledText {
- text: modelData.appName || I18n.tr("Unknown")
- font.pixelSize: Theme.fontSizeSmall
- font.weight: Font.Medium
- color: "white"
- opacity: 0.7
- elide: Text.ElideRight
- width: parent.width - timeText.implicitWidth - Theme.spacingXS
- }
-
- StyledText {
- id: timeText
- text: modelData.timeStr || ""
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- opacity: 0.5
- }
- }
-
- StyledText {
- width: parent.width
- text: modelData.summary || ""
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Medium
- color: "white"
- elide: Text.ElideRight
- maximumLineCount: 1
- visible: text.length > 0
- }
-
- StyledText {
- width: parent.width
- text: {
- const body = modelData.body || "";
- return body.replace(/<[^>]*>/g, '').replace(/\n/g, ' ');
- }
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- opacity: 0.8
- elide: Text.ElideRight
- maximumLineCount: 2
- wrapMode: Text.WordWrap
- visible: text.length > 0
- }
- }
- }
- }
-
- StyledText {
- visible: lockNotificationPanel.appNameGroups.length > 5
- text: I18n.tr("+ %1 more").arg(lockNotificationPanel.appNameGroups.length - 5)
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- opacity: 0.7
- }
- }
- }
- }
- }
- }
-
- ColumnLayout {
- id: passwordLayout
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: lockNotificationPanel.visible ? lockNotificationPanel.bottom : (dateText.visible ? dateText.bottom : clockContainer.bottom)
- anchors.topMargin: Theme.spacingL
- spacing: Theme.spacingM
- width: 380
-
- RowLayout {
- spacing: Theme.spacingL
- Layout.fillWidth: true
-
- DankCircularImage {
- Layout.preferredWidth: 60
- Layout.preferredHeight: 60
- imageSource: {
- if (PortalService.profileImage === "")
- return "";
- if (PortalService.profileImage.startsWith("/"))
- return encodeFileUrl(PortalService.profileImage);
- return PortalService.profileImage;
- }
- fallbackIcon: "person"
- visible: SettingsData.lockScreenShowProfileImage
- }
-
- Rectangle {
- property bool showPassword: false
-
- Layout.fillWidth: true
- Layout.preferredHeight: 60
- radius: Theme.cornerRadius
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
- border.color: passwordField.activeFocus ? Theme.primary : Qt.rgba(1, 1, 1, 0.3)
- border.width: passwordField.activeFocus ? 2 : 1
- visible: SettingsData.lockScreenShowPasswordField || root.passwordBuffer.length > 0
-
- Item {
- id: lockIconContainer
- anchors.left: parent.left
- anchors.leftMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- width: 20
- height: 20
-
- DankIcon {
- id: lockIcon
-
- anchors.centerIn: parent
- name: {
- if (pam.u2fPending)
- return "passkey";
- if (pam.fprint.tries >= SettingsData.maxFprintTries)
- return "fingerprint_off";
- if (pam.fprint.active)
- return "fingerprint";
- if (pam.u2f.active)
- return "passkey";
- return "lock";
- }
- size: 20
- color: {
- if (pam.fprint.tries >= SettingsData.maxFprintTries)
- return Theme.error;
- if (pam.u2fState !== "")
- return Theme.tertiary;
- return passwordField.activeFocus ? Theme.primary : Theme.surfaceVariantText;
- }
- opacity: pam.passwd.active ? 0 : 1
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
-
- TextInput {
- id: passwordField
-
- anchors.fill: parent
- anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
- anchors.rightMargin: {
- let margin = Theme.spacingM;
- if (loadingSpinner.visible) {
- margin += loadingSpinner.width;
- }
- if (enterButton.visible) {
- margin += enterButton.width + 2;
- }
- if (virtualKeyboardButton.visible) {
- margin += virtualKeyboardButton.width;
- }
- if (revealButton.visible) {
- margin += revealButton.width;
- }
- return margin;
- }
- opacity: 0
- focus: true
- enabled: !demoMode
- activeFocusOnTab: !demoMode
- echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
- onTextChanged: {
- if (!demoMode) {
- root.passwordBuffer = text;
- }
- }
- onAccepted: {
- if (!demoMode && !root.unlocking && !pam.passwd.active && !pam.u2fPending) {
- pam.passwd.start();
- }
- }
- Keys.onPressed: event => {
- if (demoMode) {
- return;
- }
-
- if (root.unlocking) {
- event.accepted = true;
- return;
- }
-
- if (event.key === Qt.Key_Escape) {
- if (pam.u2fPending) {
- pam.cancelU2fPending();
- event.accepted = true;
- return;
- }
- clear();
- }
-
- if (pam.passwd.active) {
- console.log("PAM is active, ignoring input");
- event.accepted = true;
- return;
- }
- }
-
- Component.onCompleted: {
- if (!demoMode) {
- forceActiveFocus();
- }
- }
-
- onVisibleChanged: {
- if (visible && !demoMode) {
- forceActiveFocus();
- }
- }
-
- onActiveFocusChanged: {
- if (!activeFocus && !demoMode && visible && passwordField && !powerMenu.isVisible) {
- Qt.callLater(() => {
- if (passwordField && passwordField.forceActiveFocus) {
- passwordField.forceActiveFocus();
- }
- });
- }
- }
-
- onEnabledChanged: {
- if (enabled && !demoMode && visible && passwordField && !powerMenu.isVisible) {
- Qt.callLater(() => {
- if (passwordField && passwordField.forceActiveFocus) {
- passwordField.forceActiveFocus();
- }
- });
- }
- }
- }
-
- KeyboardController {
- id: keyboardController
- target: passwordField
- rootObject: root
- }
-
- StyledText {
- id: placeholder
-
- anchors.left: lockIconContainer.right
- anchors.leftMargin: Theme.spacingM
- anchors.right: (revealButton.visible ? revealButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right))))
- anchors.rightMargin: 2
- anchors.verticalCenter: parent.verticalCenter
- text: {
- if (demoMode) {
- return "";
- }
- if (root.unlocking) {
- return "Unlocking...";
- }
- if (pam.u2fPending) {
- if (pam.u2fState === "insert")
- return "Insert your security key...";
- return "Touch your security key...";
- }
- if (pam.passwd.active) {
- return "Authenticating...";
- }
- return "Password...";
- }
- color: root.unlocking ? Theme.primary : (pam.passwd.active ? Theme.primary : Theme.outline)
- font.pixelSize: Theme.fontSizeMedium
- opacity: (demoMode || root.passwordBuffer.length === 0) ? 1 : 0
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.standardEasing
- }
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- StyledText {
- anchors.left: lockIconContainer.right
- anchors.leftMargin: Theme.spacingM
- anchors.right: (revealButton.visible ? revealButton.left : (virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right))))
- anchors.rightMargin: 2
- anchors.verticalCenter: parent.verticalCenter
- text: {
- if (demoMode) {
- return "••••••••";
- }
- if (parent.showPassword) {
- return root.passwordBuffer;
- }
- return "•".repeat(root.passwordBuffer.length);
- }
- color: Theme.surfaceText
- font.pixelSize: parent.showPassword ? Theme.fontSizeMedium : Theme.fontSizeLarge
- opacity: (demoMode || root.passwordBuffer.length > 0) ? 1 : 0
- clip: true
- elide: Text.ElideNone
- horizontalAlignment: implicitWidth > width ? Text.AlignRight : Text.AlignLeft
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.mediumDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- DankActionButton {
- id: revealButton
-
- anchors.right: virtualKeyboardButton.visible ? virtualKeyboardButton.left : (enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right))
- anchors.rightMargin: 0
- anchors.verticalCenter: parent.verticalCenter
- iconName: parent.showPassword ? "visibility_off" : "visibility"
- buttonSize: 32
- visible: !demoMode && root.passwordBuffer.length > 0 && !pam.passwd.active && !root.unlocking
- enabled: visible
- onClicked: parent.showPassword = !parent.showPassword
- }
- DankActionButton {
- id: virtualKeyboardButton
-
- anchors.right: enterButton.visible ? enterButton.left : (loadingSpinner.visible ? loadingSpinner.left : parent.right)
- anchors.rightMargin: enterButton.visible ? 0 : Theme.spacingS
- anchors.verticalCenter: parent.verticalCenter
- iconName: "keyboard"
- buttonSize: 32
- visible: !demoMode && !pam.passwd.active && !root.unlocking && !pam.u2fPending
- enabled: visible
- onClicked: {
- if (keyboardController.isKeyboardActive) {
- keyboardController.hide();
- } else {
- keyboardController.show();
- }
- }
- }
-
- Rectangle {
- id: loadingSpinner
-
- anchors.right: enterButton.visible ? enterButton.left : parent.right
- anchors.rightMargin: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- width: 24
- height: 24
- radius: 12
- color: "transparent"
- visible: !demoMode && (pam.passwd.active || root.unlocking)
-
- DankIcon {
- anchors.centerIn: parent
- name: "check_circle"
- size: 20
- color: Theme.primary
- visible: root.unlocking
-
- SequentialAnimation on scale {
- running: root.unlocking
-
- NumberAnimation {
- from: 0
- to: 1.2
- duration: Anims.durShort
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Anims.emphasizedDecel
- }
-
- NumberAnimation {
- from: 1.2
- to: 1
- duration: Anims.durShort
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Anims.emphasizedAccel
- }
- }
- }
-
- Item {
- anchors.fill: parent
- visible: pam.passwd.active && !root.unlocking
-
- Rectangle {
- width: 20
- height: 20
- radius: 10
- anchors.centerIn: parent
- color: "transparent"
- border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3)
- border.width: 2
- }
-
- Rectangle {
- width: 20
- height: 20
- radius: 10
- anchors.centerIn: parent
- color: "transparent"
- border.color: Theme.primary
- border.width: 2
-
- Rectangle {
- width: parent.width
- height: parent.height / 2
- anchors.top: parent.top
- anchors.horizontalCenter: parent.horizontalCenter
- color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.9)
- }
-
- RotationAnimation on rotation {
- running: pam.passwd.active && !root.unlocking
- loops: Animation.Infinite
- duration: Anims.durLong
- from: 0
- to: 360
- }
- }
- }
- }
-
- DankActionButton {
- id: enterButton
-
- anchors.right: parent.right
- anchors.rightMargin: 2
- anchors.verticalCenter: parent.verticalCenter
- iconName: "keyboard_return"
- buttonSize: 36
- visible: (demoMode || (!pam.passwd.active && !root.unlocking && !pam.u2fPending))
- enabled: !demoMode
- onClicked: {
- if (!demoMode && !root.unlocking && !pam.u2fPending) {
- pam.passwd.start();
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- Behavior on border.color {
- ColorAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
-
- StyledText {
- id: authFeedbackText
-
- Layout.fillWidth: true
- Layout.preferredHeight: text.length > 0 ? Math.min(implicitHeight, Math.ceil(Theme.fontSizeSmall * 4.5)) : 0
- text: root.currentAuthFeedbackText()
- color: root.authFeedbackIsHint() ? Theme.outline : Theme.error
- font.pixelSize: Theme.fontSizeSmall
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- maximumLineCount: 3
- elide: Text.ElideRight
- opacity: text.length > 0 ? 1 : 0
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
- }
-
- Row {
- anchors.top: passwordLayout.bottom
- anchors.topMargin: Theme.spacingS
- anchors.horizontalCenter: passwordLayout.horizontalCenter
- spacing: 4
- opacity: DMSService.capsLockState ? 1 : 0
-
- DankIcon {
- name: "shift_lock"
- size: 14
- color: Theme.error
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: I18n.tr("Caps Lock is on")
- font.pixelSize: Theme.fontSizeSmall
- color: Theme.error
- anchors.verticalCenter: parent.verticalCenter
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: Theme.shortDuration
- easing.type: Theme.standardEasing
- }
- }
- }
-
- StyledText {
- anchors.top: parent.top
- anchors.left: parent.left
- anchors.margins: Theme.spacingXL
- text: I18n.tr("DEMO MODE - Click anywhere to exit")
- font.pixelSize: Theme.fontSizeSmall
- color: "white"
- opacity: 0.7
- visible: demoMode
- }
-
- Row {
- anchors.top: parent.top
- anchors.right: parent.right
- anchors.margins: Theme.spacingXL
- spacing: Theme.spacingL
- visible: SettingsData.lockScreenShowSystemIcons
-
- Item {
- width: keyboardLayoutRow.width
- height: keyboardLayoutRow.height
- anchors.verticalCenter: parent.verticalCenter
- visible: {
- if (CompositorService.isNiri) {
- return NiriService.keyboardLayoutNames.length > 1;
- } else if (CompositorService.isHyprland) {
- return hyprlandLayoutCount > 1;
- }
- return false;
- }
-
- Row {
- id: keyboardLayoutRow
- spacing: 4
-
- Item {
- width: Theme.iconSize
- height: Theme.iconSize
-
- DankIcon {
- name: "keyboard"
- size: Theme.iconSize
- color: "white"
- anchors.centerIn: parent
- }
- }
-
- Item {
- width: childrenRect.width
- height: Theme.iconSize
-
- StyledText {
- text: {
- if (CompositorService.isNiri) {
- const layout = NiriService.getCurrentKeyboardLayoutName();
- if (!layout)
- return "";
- const parts = layout.split(" ");
- if (parts.length > 0) {
- return parts[0].substring(0, 2).toUpperCase();
- }
- return layout.substring(0, 2).toUpperCase();
- } else if (CompositorService.isHyprland) {
- return hyprlandCurrentLayout;
- }
- return "";
- }
- font.pixelSize: Theme.fontSizeMedium
- font.weight: Font.Light
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
-
- MouseArea {
- id: keyboardLayoutArea
- anchors.fill: parent
- enabled: !demoMode
- hoverEnabled: enabled
- cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
- onClicked: {
- if (CompositorService.isNiri) {
- NiriService.cycleKeyboardLayout();
- } else if (CompositorService.isHyprland) {
- Quickshell.execDetached(["hyprctl", "switchxkblayout", hyprlandKeyboard, "next"]);
- updateHyprlandLayout();
- }
- }
- }
- }
-
- Rectangle {
- width: 1
- height: 24
- color: Qt.rgba(255, 255, 255, 0.2)
- anchors.verticalCenter: parent.verticalCenter
- visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer
- }
-
- Row {
- spacing: Theme.spacingS
- visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer
- anchors.verticalCenter: parent.verticalCenter
-
- Item {
- width: 20
- height: Theme.iconSize
- anchors.verticalCenter: parent.verticalCenter
-
- Loader {
- active: MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing
-
- sourceComponent: Component {
- Ref {
- service: CavaService
- }
- }
- }
-
- Timer {
- running: !CavaService.cavaAvailable && MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing
- interval: 256
- repeat: true
- onTriggered: {
- CavaService.values = [Math.random() * 40 + 10, Math.random() * 60 + 20, Math.random() * 50 + 15, Math.random() * 35 + 20, Math.random() * 45 + 15, Math.random() * 55 + 25];
- }
- }
-
- Row {
- anchors.centerIn: parent
- spacing: 1.5
-
- Repeater {
- model: 6
- delegate: Rectangle {
- required property int index
-
- width: 2
- height: {
- if (MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing && CavaService.values.length > index) {
- const rawLevel = CavaService.values[index] || 0;
- const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100;
- const maxHeight = Theme.iconSize - 2;
- const minHeight = 3;
- return minHeight + (scaledLevel / 100) * (maxHeight - minHeight);
- }
- return 3;
- }
- radius: 1.5
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
-
- Behavior on height {
- NumberAnimation {
- duration: Anims.durShort
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Anims.standardDecel
- }
- }
- }
- }
- }
- }
-
- StyledText {
- text: {
- const player = MprisController.activePlayer;
- if (!player?.trackTitle)
- return "";
- const title = player.trackTitle;
- const artist = player.trackArtist || "";
- return artist ? title + " • " + artist : title;
- }
- font.pixelSize: Theme.fontSizeLarge
- color: "white"
- opacity: 0.9
- anchors.verticalCenter: parent.verticalCenter
- elide: Text.ElideRight
- width: Math.min(implicitWidth, 400)
- wrapMode: Text.NoWrap
- maximumLineCount: 1
- }
-
- Row {
- spacing: Theme.spacingXS
- anchors.verticalCenter: parent.verticalCenter
-
- Rectangle {
- width: 20
- height: 20
- radius: 10
- anchors.verticalCenter: parent.verticalCenter
- color: prevArea.containsMouse ? Qt.rgba(255, 255, 255, 0.2) : "transparent"
- visible: MprisController.activePlayer
- opacity: (MprisController.activePlayer?.canGoPrevious ?? false) ? 1 : 0.3
-
- DankIcon {
- anchors.centerIn: parent
- name: "skip_previous"
- size: 12
- color: "white"
- }
-
- MouseArea {
- id: prevArea
- anchors.fill: parent
- enabled: MprisController.activePlayer?.canGoPrevious ?? false
- hoverEnabled: enabled
- cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
- onClicked: MprisController.previousOrRewind()
- }
- }
-
- Rectangle {
- width: 24
- height: 24
- radius: 12
- anchors.verticalCenter: parent.verticalCenter
- color: MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing ? Qt.rgba(255, 255, 255, 0.9) : Qt.rgba(255, 255, 255, 0.2)
- visible: MprisController.activePlayer
-
- DankIcon {
- anchors.centerIn: parent
- name: MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing ? "pause" : "play_arrow"
- size: 14
- color: MprisController.activePlayer?.playbackState === MprisPlaybackState.Playing ? "black" : "white"
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: MprisController.activePlayer
- hoverEnabled: enabled
- cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
- onClicked: MprisController.activePlayer?.togglePlaying()
- }
- }
-
- Rectangle {
- width: 20
- height: 20
- radius: 10
- anchors.verticalCenter: parent.verticalCenter
- color: nextArea.containsMouse ? Qt.rgba(255, 255, 255, 0.2) : "transparent"
- visible: MprisController.activePlayer
- opacity: (MprisController.activePlayer?.canGoNext ?? false) ? 1 : 0.3
-
- DankIcon {
- anchors.centerIn: parent
- name: "skip_next"
- size: 12
- color: "white"
- }
-
- MouseArea {
- id: nextArea
- anchors.fill: parent
- enabled: MprisController.activePlayer?.canGoNext ?? false
- hoverEnabled: enabled
- cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
- onClicked: MprisController.activePlayer?.next()
- }
- }
- }
- }
-
- Rectangle {
- width: 1
- height: 24
- color: Qt.rgba(255, 255, 255, 0.2)
- anchors.verticalCenter: parent.verticalCenter
- visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer && WeatherService.weather.available
- }
-
- Row {
- spacing: 6
- visible: WeatherService.weather.available
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- name: WeatherService.getWeatherIcon(WeatherService.weather.wCode)
- size: Theme.iconSize
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: (SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp) + "°"
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Light
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
- }
-
- Rectangle {
- width: 1
- height: 24
- color: Qt.rgba(255, 255, 255, 0.2)
- anchors.verticalCenter: parent.verticalCenter
- visible: WeatherService.weather.available && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio) || BatteryService.batteryAvailable)
- }
-
- Row {
- spacing: Theme.spacingM
- anchors.verticalCenter: parent.verticalCenter
- visible: NetworkService.networkAvailable || (BluetoothService.available && BluetoothService.enabled) || (AudioService.sink && AudioService.sink.audio)
-
- DankIcon {
- name: "screen_record"
- size: Theme.iconSize - 2
- color: NiriService.hasActiveCast ? "white" : Qt.rgba(255, 255, 255, 0.5)
- anchors.verticalCenter: parent.verticalCenter
- visible: NiriService.hasCasts
- }
-
- DankIcon {
- name: {
- if (NetworkService.wifiToggling)
- return "sync";
- switch (NetworkService.networkStatus) {
- case "ethernet":
- return "lan";
- case "vpn":
- return NetworkService.ethernetConnected ? "lan" : NetworkService.wifiSignalIcon;
- default:
- return NetworkService.wifiSignalIcon;
- }
- }
- size: Theme.iconSize - 2
- color: NetworkService.networkStatus !== "disconnected" ? "white" : Qt.rgba(255, 255, 255, 0.5)
- anchors.verticalCenter: parent.verticalCenter
- visible: NetworkService.networkAvailable
- }
-
- DankIcon {
- name: "vpn_lock"
- size: Theme.iconSize - 2
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- visible: NetworkService.vpnAvailable && NetworkService.vpnConnected
- }
-
- DankIcon {
- name: "bluetooth"
- size: Theme.iconSize - 2
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- visible: BluetoothService.available && BluetoothService.enabled
- }
-
- DankIcon {
- name: {
- if (!AudioService.sink?.audio) {
- return "volume_up";
- }
- if (AudioService.sink.audio.muted)
- return "volume_off";
- if (AudioService.sink.audio.volume === 0)
- return "volume_mute";
- if (AudioService.sink.audio.volume * 100 < 33) {
- return "volume_down";
- }
- return "volume_up";
- }
- size: Theme.iconSize - 2
- color: (AudioService.sink && AudioService.sink.audio && (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0)) ? Qt.rgba(255, 255, 255, 0.5) : "white"
- anchors.verticalCenter: parent.verticalCenter
- visible: AudioService.sink && AudioService.sink.audio
- }
- }
-
- Rectangle {
- width: 1
- height: 24
- color: Qt.rgba(255, 255, 255, 0.2)
- anchors.verticalCenter: parent.verticalCenter
- visible: BatteryService.batteryAvailable && (NetworkService.networkStatus !== "disconnected" || BluetoothService.enabled || (AudioService.sink && AudioService.sink.audio))
- }
-
- Row {
- spacing: 4
- visible: BatteryService.batteryAvailable
- anchors.verticalCenter: parent.verticalCenter
-
- DankIcon {
- name: {
- if (BatteryService.isCharging) {
- if (BatteryService.batteryLevel >= 90) {
- return "battery_charging_full";
- }
-
- if (BatteryService.batteryLevel >= 80) {
- return "battery_charging_90";
- }
-
- if (BatteryService.batteryLevel >= 60) {
- return "battery_charging_80";
- }
-
- if (BatteryService.batteryLevel >= 50) {
- return "battery_charging_60";
- }
-
- if (BatteryService.batteryLevel >= 30) {
- return "battery_charging_50";
- }
-
- if (BatteryService.batteryLevel >= 20) {
- return "battery_charging_30";
- }
-
- return "battery_charging_20";
- }
- if (BatteryService.isPluggedIn) {
- if (BatteryService.batteryLevel >= 90) {
- return "battery_charging_full";
- }
-
- if (BatteryService.batteryLevel >= 80) {
- return "battery_charging_90";
- }
-
- if (BatteryService.batteryLevel >= 60) {
- return "battery_charging_80";
- }
-
- if (BatteryService.batteryLevel >= 50) {
- return "battery_charging_60";
- }
-
- if (BatteryService.batteryLevel >= 30) {
- return "battery_charging_50";
- }
-
- if (BatteryService.batteryLevel >= 20) {
- return "battery_charging_30";
- }
-
- return "battery_charging_20";
- }
- if (BatteryService.batteryLevel >= 95) {
- return "battery_full";
- }
-
- if (BatteryService.batteryLevel >= 85) {
- return "battery_6_bar";
- }
-
- if (BatteryService.batteryLevel >= 70) {
- return "battery_5_bar";
- }
-
- if (BatteryService.batteryLevel >= 55) {
- return "battery_4_bar";
- }
-
- if (BatteryService.batteryLevel >= 40) {
- return "battery_3_bar";
- }
-
- if (BatteryService.batteryLevel >= 25) {
- return "battery_2_bar";
- }
-
- return "battery_1_bar";
- }
- size: Theme.iconSize
- color: {
- if (BatteryService.isLowBattery && !BatteryService.isCharging) {
- return Theme.error;
- }
-
- if (BatteryService.isCharging || BatteryService.isPluggedIn) {
- return Theme.primary;
- }
-
- return "white";
- }
- anchors.verticalCenter: parent.verticalCenter
- }
-
- StyledText {
- text: BatteryService.batteryLevel + "%"
- font.pixelSize: Theme.fontSizeLarge
- font.weight: Font.Light
- color: "white"
- anchors.verticalCenter: parent.verticalCenter
- }
- }
- }
-
- DankActionButton {
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.margins: Theme.spacingXL
- visible: SettingsData.lockScreenShowPowerActions
- iconName: "power_settings_new"
- iconColor: Theme.error
- buttonSize: 40
- onClicked: {
- if (demoMode) {
- console.log("Demo: Power Menu");
- } else {
- powerMenu.show();
- }
- }
- }
- }
-
- Pam {
- id: pam
- lockSecured: !demoMode
- onUnlockRequested: {
- root.unlocking = true;
- lockerReadyArmed = false;
- passwordField.text = "";
- root.passwordBuffer = "";
- root.unlockRequested();
- }
- onStateChanged: {
- root.pamState = state;
- if (state !== "") {
- root.unlocking = false;
- placeholderDelay.restart();
- passwordField.text = "";
- root.passwordBuffer = "";
- }
- }
- onU2fPendingChanged: {
- if (u2fPending) {
- passwordField.text = "";
- root.passwordBuffer = "";
- if (keyboardController.isKeyboardActive)
- keyboardController.hide();
- }
- }
- }
-
- Connections {
- target: pam
-
- function onUnlockInProgressChanged() {
- if (!pam.unlockInProgress && root.unlocking)
- root.unlocking = false;
- }
- }
-
- Binding {
- target: pam
- property: "buffer"
- value: root.passwordBuffer
- }
-
- Timer {
- id: placeholderDelay
-
- interval: 4000
- onTriggered: root.pamState = ""
- }
-
- MouseArea {
- anchors.fill: parent
- enabled: demoMode
- onClicked: root.unlockRequested()
- }
-
- LockPowerMenu {
- id: powerMenu
- showLogout: true
- onClosed: {
- if (!demoMode && passwordField && passwordField.forceActiveFocus) {
- Qt.callLater(() => passwordField.forceActiveFocus());
- }
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenDemo.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenDemo.qml
deleted file mode 100644
index e13eac9..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockScreenDemo.qml
+++ /dev/null
@@ -1,46 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Wayland
-
-PanelWindow {
- id: root
-
- property bool demoActive: false
-
- visible: demoActive
-
- anchors {
- top: true
- bottom: true
- left: true
- right: true
- }
-
- WlrLayershell.layer: WlrLayershell.Overlay
- WlrLayershell.exclusiveZone: -1
- WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
-
- color: "transparent"
-
- function showDemo(): void {
- console.log("Showing lock screen demo");
- demoActive = true;
- }
-
- function hideDemo(): void {
- console.log("Hiding lock screen demo");
- demoActive = false;
- }
-
- Loader {
- anchors.fill: parent
- active: demoActive
- sourceComponent: LockScreenContent {
- demoMode: true
- screenName: root.screen?.name ?? ""
- onUnlockRequested: root.hideDemo()
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockSurface.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockSurface.qml
deleted file mode 100644
index 9d1beae..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/LockSurface.qml
+++ /dev/null
@@ -1,73 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell.Wayland
-import qs.Common
-
-FocusScope {
- id: root
-
- required property WlSessionLock lock
- required property string sharedPasswordBuffer
- required property string screenName
- required property bool isLocked
-
- signal passwordChanged(string newPassword)
- signal unlockRequested
-
- Keys.onPressed: event => {
- if (videoScreensaver.active && videoScreensaver.inputEnabled) {
- videoScreensaver.dismiss();
- event.accepted = true;
- }
- }
-
- Rectangle {
- anchors.fill: parent
- color: "transparent"
- }
-
- LockScreenContent {
- id: lockContent
-
- anchors.fill: parent
- demoMode: false
- passwordBuffer: root.sharedPasswordBuffer
- screenName: root.screenName
- enabled: !videoScreensaver.active
- focus: !videoScreensaver.active
- opacity: videoScreensaver.active ? 0 : 1
- onUnlockRequested: root.unlockRequested()
- onPasswordBufferChanged: {
- if (root.sharedPasswordBuffer !== passwordBuffer) {
- root.passwordChanged(passwordBuffer);
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: 200
- }
- }
- }
-
- VideoScreensaver {
- id: videoScreensaver
- anchors.fill: parent
- screenName: root.screenName
- }
-
- Component.onCompleted: forceActiveFocus()
-
- onIsLockedChanged: {
- if (isLocked) {
- forceActiveFocus();
- lockContent.resetLockState();
- if (SettingsData.lockScreenVideoEnabled) {
- videoScreensaver.start();
- }
- return;
- }
- lockContent.unlocking = false;
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Pam.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Pam.qml
deleted file mode 100644
index f5e7859..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/Pam.qml
+++ /dev/null
@@ -1,405 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell
-import Quickshell.Io
-import Quickshell.Services.Pam
-import qs.Common
-
-Scope {
- id: root
-
- property bool lockSecured: false
- property bool unlockInProgress: false
-
- readonly property alias passwd: passwd
- readonly property alias fprint: fprint
- readonly property alias u2f: u2f
- property string lockMessage
- property string state
- property string fprintState
- property string u2fState
- property bool u2fPending: false
- property string buffer
-
- signal flashMsg
- signal unlockRequested
-
- function resetAuthFlows(): void {
- passwd.abort();
- fprint.abort();
- u2f.abort();
- errorRetry.running = false;
- u2fErrorRetry.running = false;
- u2fPendingTimeout.running = false;
- passwdActiveTimeout.running = false;
- unlockRequestTimeout.running = false;
- root.u2fPending = false;
- root.u2fState = "";
- root.unlockInProgress = false;
- }
-
- function recoverFromAuthStall(newState: string): void {
- resetAuthFlows();
- root.state = newState;
- flashMsg();
- stateReset.restart();
- fprint.checkAvail();
- u2f.checkAvail();
- }
-
- function completeUnlock(): void {
- if (!root.unlockInProgress) {
- root.unlockInProgress = true;
- passwd.abort();
- fprint.abort();
- u2f.abort();
- errorRetry.running = false;
- u2fErrorRetry.running = false;
- u2fPendingTimeout.running = false;
- root.u2fPending = false;
- root.u2fState = "";
- unlockRequestTimeout.restart();
- unlockRequested();
- }
- }
-
- function proceedAfterPrimaryAuth(): void {
- if (SettingsData.enableU2f && SettingsData.u2fMode === "and" && u2f.available) {
- u2f.startForSecondFactor();
- } else {
- completeUnlock();
- }
- }
-
- function cancelU2fPending(): void {
- if (!root.u2fPending)
- return;
- u2f.abort();
- u2fErrorRetry.running = false;
- u2fPendingTimeout.running = false;
- root.u2fPending = false;
- root.u2fState = "";
- fprint.checkAvail();
- }
-
- FileView {
- id: dankshellConfigWatcher
-
- path: "/etc/pam.d/dankshell"
- printErrors: false
- }
-
- FileView {
- id: nixosMarker
-
- path: "/etc/NIXOS"
- printErrors: false
- }
-
- FileView {
- id: u2fConfigWatcher
-
- path: "/etc/pam.d/dankshell-u2f"
- printErrors: false
- }
-
- // Detects Nix-installed DMS on non-NixOS systems
- readonly property bool runningFromNixStore: Quickshell.shellDir.startsWith("/nix/store/")
-
- PamContext {
- id: passwd
-
- config: dankshellConfigWatcher.loaded ? "dankshell" : "login"
- configDirectory: (dankshellConfigWatcher.loaded || nixosMarker.loaded || root.runningFromNixStore) ? "/etc/pam.d" : Quickshell.shellDir + "/assets/pam"
-
- onMessageChanged: {
- if (message.startsWith("The account is locked")) {
- root.lockMessage = message;
- } else if (root.lockMessage && message.endsWith(" left to unlock)")) {
- root.lockMessage += "\n" + message;
- } else if (root.lockMessage && message && message.length > 0) {
- root.lockMessage = "";
- }
- }
-
- onResponseRequiredChanged: {
- if (!responseRequired)
- return;
-
- respond(root.buffer);
- }
-
- onCompleted: res => {
- if (res === PamResult.Success) {
- if (!root.unlockInProgress) {
- fprint.abort();
- root.proceedAfterPrimaryAuth();
- }
- return;
- }
-
- unlockRequestTimeout.running = false;
- root.unlockInProgress = false;
- root.u2fPending = false;
- root.u2fState = "";
- u2fPendingTimeout.running = false;
- u2f.abort();
-
- if (res === PamResult.Error)
- root.state = "error";
- else if (res === PamResult.MaxTries)
- root.state = "max";
- else if (res === PamResult.Failed)
- root.state = "fail";
-
- root.flashMsg();
- stateReset.restart();
- }
- }
-
- Connections {
- target: passwd
-
- function onActiveChanged() {
- if (passwd.active) {
- passwdActiveTimeout.restart();
- } else {
- passwdActiveTimeout.running = false;
- }
- }
- }
-
- PamContext {
- id: fprint
-
- property bool available: SettingsData.lockFingerprintReady
- property int tries
- property int errorTries
-
- function checkAvail(): void {
- if (!available || !SettingsData.enableFprint || !root.lockSecured) {
- abort();
- return;
- }
-
- tries = 0;
- errorTries = 0;
- start();
- }
-
- config: "fprint"
- configDirectory: Quickshell.shellDir + "/assets/pam"
-
- onCompleted: res => {
- if (!available)
- return;
-
- if (res === PamResult.Success) {
- if (!root.unlockInProgress) {
- passwd.abort();
- root.proceedAfterPrimaryAuth();
- }
- return;
- }
-
- if (res === PamResult.Error) {
- root.fprintState = "error";
- errorTries++;
- if (errorTries < 5) {
- abort();
- errorRetry.restart();
- }
- } else if (res === PamResult.MaxTries) {
- tries++;
- if (tries < SettingsData.maxFprintTries) {
- root.fprintState = "fail";
- start();
- } else {
- root.fprintState = "max";
- abort();
- }
- }
-
- root.flashMsg();
- fprintStateReset.start();
- }
- }
-
- PamContext {
- id: u2f
-
- property bool available: SettingsData.lockU2fReady
-
- function checkAvail(): void {
- if (!available || !SettingsData.enableU2f || !root.lockSecured) {
- abort();
- return;
- }
-
- if (SettingsData.u2fMode === "or") {
- start();
- }
- }
-
- function startForSecondFactor(): void {
- if (!available || !SettingsData.enableU2f) {
- root.completeUnlock();
- return;
- }
- abort();
- root.u2fPending = true;
- root.u2fState = "";
- u2fPendingTimeout.restart();
- start();
- }
-
- config: u2fConfigWatcher.loaded ? "dankshell-u2f" : "u2f"
- configDirectory: u2fConfigWatcher.loaded ? "/etc/pam.d" : Quickshell.shellDir + "/assets/pam"
-
- onMessageChanged: {
- if (message.toLowerCase().includes("touch"))
- root.u2fState = "waiting";
- }
-
- onCompleted: res => {
- if (!available || root.unlockInProgress)
- return;
-
- if (res === PamResult.Success) {
- root.completeUnlock();
- return;
- }
-
- if (res === PamResult.Error || res === PamResult.MaxTries || res === PamResult.Failed) {
- abort();
-
- if (root.u2fPending) {
- if (root.u2fState === "waiting") {
- // AND mode: device was found but auth failed → back to password
- root.u2fPending = false;
- root.u2fState = "";
- fprint.checkAvail();
- } else {
- // AND mode: no device found → keep pending, show "Insert...", retry
- root.u2fState = "insert";
- u2fErrorRetry.restart();
- }
- } else {
- // OR mode: prompt to insert key, silently retry
- root.u2fState = "insert";
- u2fErrorRetry.restart();
- }
- }
- }
- }
-
- Timer {
- id: errorRetry
-
- interval: 800
- onTriggered: fprint.start()
- }
-
- Timer {
- id: u2fErrorRetry
-
- interval: 800
- onTriggered: u2f.start()
- }
-
- Timer {
- id: u2fPendingTimeout
-
- interval: 30000
- onTriggered: root.cancelU2fPending()
- }
-
- Timer {
- id: passwdActiveTimeout
-
- interval: 15000
- onTriggered: {
- if (passwd.active)
- root.recoverFromAuthStall("error");
- }
- }
-
- Timer {
- id: unlockRequestTimeout
-
- interval: 8000
- onTriggered: {
- if (root.unlockInProgress)
- root.recoverFromAuthStall("error");
- }
- }
-
- Timer {
- id: stateReset
-
- interval: 4000
- onTriggered: {
- if (root.state !== "max")
- root.state = "";
- }
- }
-
- Timer {
- id: fprintStateReset
-
- interval: 4000
- onTriggered: {
- root.fprintState = "";
- fprint.errorTries = 0;
- }
- }
-
- onLockSecuredChanged: {
- if (lockSecured) {
- SettingsData.refreshAuthAvailability();
- root.state = "";
- root.fprintState = "";
- root.u2fState = "";
- root.u2fPending = false;
- root.lockMessage = "";
- root.resetAuthFlows();
- fprint.checkAvail();
- u2f.checkAvail();
- } else {
- root.resetAuthFlows();
- }
- }
-
- Connections {
- target: SettingsData
-
- function onEnableFprintChanged(): void {
- fprint.checkAvail();
- }
-
- function onLockFingerprintReadyChanged(): void {
- fprint.checkAvail();
- }
-
- function onEnableU2fChanged(): void {
- u2f.checkAvail();
- }
-
- function onLockU2fReadyChanged(): void {
- u2f.checkAvail();
- }
-
- function onU2fModeChanged(): void {
- if (root.lockSecured) {
- u2f.abort();
- u2fErrorRetry.running = false;
- u2fPendingTimeout.running = false;
- unlockRequestTimeout.running = false;
- root.u2fPending = false;
- root.u2fState = "";
- u2f.checkAvail();
- }
- }
- }
-}
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/VideoScreensaver.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/VideoScreensaver.qml
deleted file mode 100644
index 129f507..0000000
--- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Modules/Lock/VideoScreensaver.qml
+++ /dev/null
@@ -1,200 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import QtQuick
-import Quickshell.Io
-import qs.Common
-import qs.Services
-
-Item {
- id: root
-
- required property string screenName
- property bool active: false
- property string videoSource: ""
- property bool inputEnabled: false
- property point lastMousePos: Qt.point(-1, -1)
- property bool mouseInitialized: false
- property var videoPlayer: null
-
- signal dismissed
-
- visible: active
- z: 1000
-
- Rectangle {
- id: background
- anchors.fill: parent
- color: "black"
- visible: root.active
- }
-
- Timer {
- id: inputEnableTimer
- interval: 500
- onTriggered: root.inputEnabled = true
- }
-
- Process {
- id: videoPicker
- property string result: ""
- property string folder: ""
-
- command: ["sh", "-c", "find '" + folder + "' -maxdepth 1 -type f \\( " + "-iname '*.mp4' -o -iname '*.mkv' -o -iname '*.webm' -o " + "-iname '*.mov' -o -iname '*.avi' -o -iname '*.m4v' " + "\\) 2>/dev/null | shuf -n1"]
-
- stdout: SplitParser {
- onRead: data => {
- const path = data.trim();
- if (path) {
- videoPicker.result = path;
- root.videoSource = "file://" + path;
- }
- }
- }
-
- onExited: exitCode => {
- if (exitCode !== 0 || !videoPicker.result) {
- console.warn("VideoScreensaver: no video found in folder");
- ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("No video found in folder"));
- root.dismiss();
- }
- }
- }
-
- Process {
- id: fileChecker
- command: ["test", "-d", SettingsData.lockScreenVideoPath]
-
- onExited: exitCode => {
- const isDir = exitCode === 0;
- const videoPath = SettingsData.lockScreenVideoPath;
-
- if (isDir) {
- videoPicker.folder = videoPath;
- videoPicker.running = true;
- } else if (SettingsData.lockScreenVideoCycling) {
- const parentFolder = videoPath.substring(0, videoPath.lastIndexOf('/'));
- videoPicker.folder = parentFolder;
- videoPicker.running = true;
- } else {
- root.videoSource = "file://" + videoPath;
- }
- }
- }
-
- function createVideoPlayer() {
- if (videoPlayer)
- return true;
-
- try {
- videoPlayer = Qt.createQmlObject(`
- import QtQuick
- import QtMultimedia
- Video {
- anchors.fill: parent
- fillMode: VideoOutput.PreserveAspectCrop
- loops: MediaPlayer.Infinite
- volume: 0
- }
- `, background, "VideoScreensaver.VideoPlayer");
-
- videoPlayer.errorOccurred.connect((error, errorString) => {
- console.warn("VideoScreensaver: playback error:", errorString);
- ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("Playback error: ") + errorString);
- root.dismiss();
- });
-
- return true;
- } catch (e) {
- console.warn("VideoScreensaver: Failed to create video player:", e);
- return false;
- }
- }
-
- function destroyVideoPlayer() {
- if (videoPlayer) {
- videoPlayer.stop();
- videoPlayer.destroy();
- videoPlayer = null;
- }
- }
-
- function start() {
- if (!SettingsData.lockScreenVideoEnabled || !SettingsData.lockScreenVideoPath)
- return;
-
- if (!MultimediaService.available) {
- ToastService.showError(I18n.tr("Video Screensaver"), I18n.tr("QtMultimedia is not available"));
- return;
- }
-
- if (!createVideoPlayer())
- return;
-
- videoPicker.result = "";
- videoPicker.folder = "";
- inputEnabled = false;
- mouseInitialized = false;
- lastMousePos = Qt.point(-1, -1);
- active = true;
- inputEnableTimer.start();
- fileChecker.running = true;
- }
-
- function dismiss() {
- if (!active)
- return;
- destroyVideoPlayer();
- inputEnabled = false;
- active = false;
- videoSource = "";
- dismissed();
- }
-
- onVideoSourceChanged: {
- if (videoSource && active && videoPlayer) {
- videoPlayer.source = videoSource;
- videoPlayer.play();
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- enabled: root.active && root.inputEnabled
- hoverEnabled: true
- propagateComposedEvents: false
-
- onPositionChanged: mouse => {
- if (!root.mouseInitialized) {
- root.lastMousePos = Qt.point(mouse.x, mouse.y);
- root.mouseInitialized = true;
- return;
- }
- var dx = Math.abs(mouse.x - root.lastMousePos.x);
- var dy = Math.abs(mouse.y - root.lastMousePos.y);
- if (dx > 5 || dy > 5) {
- root.dismiss();
- }
- }
- onClicked: root.dismiss()
- onPressed: root.dismiss()
- onWheel: root.dismiss()
- }
-
- Connections {
- target: IdleService
-
- function onLockRequested() {
- if (SettingsData.lockScreenVideoEnabled && !root.active) {
- root.start();
- }
- }
-
- function onFadeToLockRequested() {
- if (SettingsData.lockScreenVideoEnabled && !root.active) {
- IdleService.cancelFadeToLock();
- root.start();
- }
- }
- }
-}