From 15ffd6d5b00f34a4202b9f0db6f05a7d1374d4ed Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 13 Jun 2025 13:31:06 -0400 Subject: [PATCH] feat: init lockscreen --- ShellSettings.qml | 2 +- bar/battery/BatteryIndicator.qml | 5 + bar/systray/TrayMenuEntry.qml | 2 - lockscreen/Controller.qml | 41 ++++++ lockscreen/LockContext.qml | 53 +++++++ lockscreen/LockSurface.qml | 198 +++++++++++++++++++++++++++ lockscreen/LoginField.qml | 92 +++++++++++++ lockscreen/README.md | 10 ++ lockscreen/image.png | Bin 0 -> 21411 bytes lockscreen/pam/fingerprint.conf | 1 + lockscreen/pam/password.conf | 1 + lockscreen/test.qml | 25 ++++ notifications/NotificationCenter.qml | 2 +- shell.qml | 5 + 14 files changed, 433 insertions(+), 4 deletions(-) create mode 100644 lockscreen/Controller.qml create mode 100644 lockscreen/LockContext.qml create mode 100644 lockscreen/LockSurface.qml create mode 100644 lockscreen/LoginField.qml create mode 100644 lockscreen/README.md create mode 100644 lockscreen/image.png create mode 100644 lockscreen/pam/fingerprint.conf create mode 100644 lockscreen/pam/password.conf create mode 100644 lockscreen/test.qml diff --git a/ShellSettings.qml b/ShellSettings.qml index 8ad1dfe..75882cc 100644 --- a/ShellSettings.qml +++ b/ShellSettings.qml @@ -11,7 +11,7 @@ Singleton { FileView { path: `${Quickshell.env("XDG_DATA_HOME")}/quickshell/settings.json` watchChanges: true - onFileChanged: reload() + // onFileChanged: reload() onAdapterUpdated: writeAdapter() blockLoading: true diff --git a/bar/battery/BatteryIndicator.qml b/bar/battery/BatteryIndicator.qml index fed696f..d2e97f5 100644 --- a/bar/battery/BatteryIndicator.qml +++ b/bar/battery/BatteryIndicator.qml @@ -49,6 +49,11 @@ Item { anchors.fill: parent // placeholder for now + + // Text { + // text + // } + ComboBox { model: ["Power Save", "Balanced", "Performance"] currentIndex: PowerProfiles.profile diff --git a/bar/systray/TrayMenuEntry.qml b/bar/systray/TrayMenuEntry.qml index 1854fb7..8c5c9d4 100644 --- a/bar/systray/TrayMenuEntry.qml +++ b/bar/systray/TrayMenuEntry.qml @@ -105,8 +105,6 @@ ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true - Layout.leftMargin: 6 - Layout.rightMargin: 6 } Item { diff --git a/lockscreen/Controller.qml b/lockscreen/Controller.qml new file mode 100644 index 0000000..d3ba238 --- /dev/null +++ b/lockscreen/Controller.qml @@ -0,0 +1,41 @@ +pragma ComponentBehavior: Bound + +import Quickshell +import Quickshell.Io +import Quickshell.Wayland + +Scope { + id: root + + PersistentProperties { + id: persist + property bool locked: false + } + + IpcHandler { + target: "lockscreen" + + function lock(): void { + persist.locked = true; + } + } + + LockContext { + id: passwordContext + + onUnlocked: persist.locked = false + } + + WlSessionLock { + id: lock + + locked: persist.locked + + WlSessionLockSurface { + LockSurface { + anchors.fill: parent + context: passwordContext + } + } + } +} diff --git a/lockscreen/LockContext.qml b/lockscreen/LockContext.qml new file mode 100644 index 0000000..fa7b85f --- /dev/null +++ b/lockscreen/LockContext.qml @@ -0,0 +1,53 @@ +import QtQuick +import Quickshell +import Quickshell.Services.Pam + +Scope { + id: root + + property string currentText: "" + property bool unlockInProgress: false + property bool showFailure: false + signal unlocked + signal failed + + // Clear the failure text once the user starts typing. + onCurrentTextChanged: showFailure = false + + function tryUnlock() { + if (currentText === "") + return; + + root.unlockInProgress = true; + pam.start(); + } + + PamContext { + id: pam + + // Its best to have a custom pam config for quickshell, as the system one + // might not be what your interface expects, and break in some way. + // This particular example only supports passwords. + configDirectory: "pam" + config: "password.conf" + + // pam_unix will ask for a response for the password prompt + onPamMessage: { + if (this.responseRequired) { + this.respond(root.currentText); + } + } + + // pam_unix won't send any important messages so all we need is the completion status. + onCompleted: result => { + if (result == PamResult.Success) { + root.unlocked(); + root.currentText = ""; + } else { + root.showFailure = true; + } + + root.unlockInProgress = false; + } + } +} diff --git a/lockscreen/LockSurface.qml b/lockscreen/LockSurface.qml new file mode 100644 index 0000000..9b7d854 --- /dev/null +++ b/lockscreen/LockSurface.qml @@ -0,0 +1,198 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Qt5Compat.GraphicalEffects +import ".." + +Rectangle { + id: root + color: Window.active ? ShellSettings.colors["surface"] : ShellSettings.colors["surface_dim"] + required property LockContext context + + Item { + anchors.fill: parent + + Image { + id: bgImage + source: ShellSettings.settings.wallpaperUrl + fillMode: Image.PreserveAspectCrop + anchors.fill: parent + visible: false + } + + FastBlur { + anchors.fill: bgImage + source: bgImage + radius: 80 + transparentBorder: true + } + + Rectangle { + anchors.fill: parent + color: "black" + opacity: 0.3 + } + + Rectangle { + anchors.fill: parent + color: "transparent" + + gradient: Gradient { + GradientStop { + position: 0.0 + color: Qt.rgba(0, 0, 0, 0.2) + } + GradientStop { + position: 0.5 + color: Qt.rgba(0, 0, 0, 0.1) + } + GradientStop { + position: 1.0 + color: Qt.rgba(0, 0, 0, 0.4) + } + } + } + } + + // Date and time display + ColumnLayout { + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: 120 + } + spacing: 10 + + Text { + id: clock + horizontalAlignment: Text.AlignHCenter + renderType: Text.NativeRendering + font.pointSize: 72 + font.weight: Font.Light + color: "white" + text: { + const now = this.date; + let hours = now.getHours(); + const minutes = now.getMinutes().toString().padStart(2, '0'); + const ampm = hours >= 12 ? 'PM' : 'AM'; + hours = hours % 12; + hours = hours ? hours : 12; // 0 should be 12 + return `${hours}:${minutes}`; + } + + property var date: new Date() + Layout.alignment: Qt.AlignHCenter + + Timer { + running: true + repeat: true + interval: 1000 + onTriggered: clock.date = new Date() + } + + layer.enabled: true + layer.effect: DropShadow { + horizontalOffset: 0 + verticalOffset: 0 + radius: 20 + samples: 41 + color: Qt.rgba(1, 1, 1, 0.3) + } + } + } + + // login section + ColumnLayout { + visible: Window.active + anchors.centerIn: parent + spacing: 30 + + Rectangle { + id: profileImage + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: 120 + Layout.preferredHeight: 120 + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: profileImage.width + height: profileImage.height + radius: width / 2 + color: "black" + } + } + + Image { + source: "root:resources/general/pfp.png" + anchors.fill: parent + } + } + + // password input, should probably split this out into a seperate comp + LoginField { + id: passwordBox + enabled: !root.context.unlockInProgress + + Layout.preferredWidth: 250 + Layout.preferredHeight: 30 + Layout.maximumHeight: 30 + Layout.alignment: Qt.AlignHCenter + + onTextChanged: root.context.currentText = this.text + onAccepted: root.context.tryUnlock() + + Connections { + target: root.context + + function onCurrentTextChanged() { + if (!passwordBox.shaking) { + passwordBox.text = root.context.currentText; + } + } + + function onShowFailureChanged() { + if (root.context.showFailure && !passwordBox.shaking) { + passwordBox.shaking = true; + } + } + } + } + } + + // hint text + Text { + text: "Press Enter to unlock" + color: Qt.rgba(1, 1, 1, 0.5) + font.pointSize: 12 + horizontalAlignment: Text.AlignHCenter + opacity: passwordBox.text.length > 0 ? 1.0 : 0.0 + + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.bottom + bottomMargin: 60 + } + + Behavior on opacity { + NumberAnimation { + duration: 300 + } + } + } + + // testing button + Button { + visible: false + text: "Emergency Unlock" + onClicked: root.context.unlocked() + + anchors { + right: parent.right + bottom: parent.bottom + margins: 20 + } + } +} diff --git a/lockscreen/LoginField.qml b/lockscreen/LoginField.qml new file mode 100644 index 0000000..f387a17 --- /dev/null +++ b/lockscreen/LoginField.qml @@ -0,0 +1,92 @@ +import QtQuick +import QtQuick.Controls +import Qt5Compat.GraphicalEffects + +TextField { + id: root + color: "white" + scale: activeFocus ? 1.05 : 1.0 + padding: 8 + focus: true + echoMode: TextInput.Password + inputMethodHints: Qt.ImhSensitiveData + font.pointSize: 11 + horizontalAlignment: Text.AlignHCenter + + background: Rectangle { + color: Qt.rgba(1, 1, 1, 0.1) + border.color: root.activeFocus ? Qt.rgba(1, 1, 1, 0.5) : Qt.rgba(1, 1, 1, 0.2) + border.width: 1 + radius: 8 + + layer.enabled: true + layer.effect: FastBlur { + radius: 10 + transparentBorder: true + } + } + + transform: Translate { + id: shakeTransform + x: 0 + } + + property bool shaking: false + + onShakingChanged: { + if (shaking) + shakeAnimation.start(); + } + + Behavior on scale { + NumberAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } + + SequentialAnimation { + id: shakeAnimation + + NumberAnimation { + target: shakeTransform + property: "x" + to: -8 + duration: 50 + easing.type: Easing.OutQuad + } + NumberAnimation { + target: shakeTransform + property: "x" + to: 8 + duration: 100 + easing.type: Easing.InOutQuad + } + NumberAnimation { + target: shakeTransform + property: "x" + to: -6 + duration: 80 + easing.type: Easing.InOutQuad + } + NumberAnimation { + target: shakeTransform + property: "x" + to: 6 + duration: 80 + easing.type: Easing.InOutQuad + } + NumberAnimation { + target: shakeTransform + property: "x" + to: -3 + duration: 60 + easing.type: Easing.InOutQuad + } + + onFinished: { + root.shaking = false; + root.text = ""; + } + } +} diff --git a/lockscreen/README.md b/lockscreen/README.md new file mode 100644 index 0000000..1926b9b --- /dev/null +++ b/lockscreen/README.md @@ -0,0 +1,10 @@ +# Lockscreen + +This is a simple but functional lockscreen that follows the system color scheme. +The only authentication method it supports is a password. + +You can run the lockscreen with `quickshell -p shell.qml`. + +You can run the lockscreen in test mode (as a window) with `quickshell -p test.qml`. + +![](./image.png) diff --git a/lockscreen/image.png b/lockscreen/image.png new file mode 100644 index 0000000000000000000000000000000000000000..f9d25d3a579825277cf0efd160802abe4edd8148 GIT binary patch literal 21411 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 literal 0 HcmV?d00001 diff --git a/lockscreen/pam/fingerprint.conf b/lockscreen/pam/fingerprint.conf new file mode 100644 index 0000000..14e89bd --- /dev/null +++ b/lockscreen/pam/fingerprint.conf @@ -0,0 +1 @@ +auth sufficient pam_fprintd.so diff --git a/lockscreen/pam/password.conf b/lockscreen/pam/password.conf new file mode 100644 index 0000000..7e5d75a --- /dev/null +++ b/lockscreen/pam/password.conf @@ -0,0 +1 @@ +auth required pam_unix.so diff --git a/lockscreen/test.qml b/lockscreen/test.qml new file mode 100644 index 0000000..22dddb9 --- /dev/null +++ b/lockscreen/test.qml @@ -0,0 +1,25 @@ +import QtQuick +import Quickshell + +ShellRoot { + LockContext { + id: lockContext + onUnlocked: Qt.quit(); + } + + FloatingWindow { + LockSurface { + anchors.fill: parent + context: lockContext + } + } + + // exit the example if the window closes + Connections { + target: Quickshell + + function onLastWindowClosed() { + Qt.quit(); + } + } +} diff --git a/notifications/NotificationCenter.qml b/notifications/NotificationCenter.qml index b682f68..90c3cba 100644 --- a/notifications/NotificationCenter.qml +++ b/notifications/NotificationCenter.qml @@ -42,7 +42,7 @@ Singleton { id: notificationPanel color: "red" implicitWidth: 500 - exclusionMode: ExclusionMode.Normal + exclusionMode: ExclusionMode.Ignore // WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive anchors { top: true diff --git a/shell.qml b/shell.qml index 3c4981c..b5d2452 100644 --- a/shell.qml +++ b/shell.qml @@ -8,6 +8,7 @@ import "notifications" as Notifications import "volume-osd" as VolumeOSD import "settings" as Settings import "launcher" as Launcher +import "lockscreen" as LockScreen import "wallpaper" as Wallpaper import "screencapture" as ScreenCapture @@ -29,6 +30,10 @@ ShellRoot { Bar.Bar { screen: scope.modelData } + + LockScreen.Controller { + + } } }