From d388842a8744aa9704159c12d1eaa841c11dee9d Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 8 Mar 2024 02:30:44 -0800 Subject: [PATCH] Quickshell lockscreen --- modules/hyprland/default.nix | 6 ++- modules/hyprland/hyprland.conf | 2 + modules/hyprland/lockscreen/AuthContext.qml | 43 +++++++++++++++++ modules/hyprland/lockscreen/Lockscreen.qml | 51 +++++++++++++++++++++ modules/hyprland/lockscreen/shell.qml | 32 +++++++++++++ modules/hyprland/lockscreen/test.qml | 21 +++++++++ 6 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 modules/hyprland/lockscreen/AuthContext.qml create mode 100644 modules/hyprland/lockscreen/Lockscreen.qml create mode 100644 modules/hyprland/lockscreen/shell.qml create mode 100644 modules/hyprland/lockscreen/test.qml diff --git a/modules/hyprland/default.nix b/modules/hyprland/default.nix index d4371ba..de1104f 100644 --- a/modules/hyprland/default.nix +++ b/modules/hyprland/default.nix @@ -1,5 +1,5 @@ { system, inputs, impurity, lib, config, pkgs, ... }: let - inherit (inputs) hyprland hyprpaper hyprland-hy3; + inherit (inputs) hyprland hyprpaper hyprland-hy3 quickshell; # I blame home manager wrapper = pkgs.callPackage ({ ... }: pkgs.writeShellScriptBin "hyprland" '' @@ -52,6 +52,10 @@ in { wrapper hyprpaper + pamtester # quickshell lockscreen + quickshell.packages.${system}.default + (writeShellScriptBin "quickshell-lock" "quickshell -c ${impurity.link ./lockscreen/shell.qml}") + # environment programs wl-clipboard grim diff --git a/modules/hyprland/hyprland.conf b/modules/hyprland/hyprland.conf index 160afb6..10e3345 100644 --- a/modules/hyprland/hyprland.conf +++ b/modules/hyprland/hyprland.conf @@ -163,6 +163,8 @@ bind = ,XF86AudioPrev, exec, playerctl previous bind = $mod+SHIFT, s, exec, grim -g "$(slurp)" - | wl-copy +bind = $mod, PERIOD, exec, quickshell-lock + bind = $mod, h, hy3:movefocus, l bind = $mod, j, hy3:movefocus, d bind = $mod, k, hy3:movefocus, u diff --git a/modules/hyprland/lockscreen/AuthContext.qml b/modules/hyprland/lockscreen/AuthContext.qml new file mode 100644 index 0000000..53ba63d --- /dev/null +++ b/modules/hyprland/lockscreen/AuthContext.qml @@ -0,0 +1,43 @@ +import QtQuick +import Quickshell +import Quickshell.Io + +QtObject { + property int status: AuthContext.Status.FirstEntry + signal success(); + + enum Status { + FirstEntry, + Authenticating, + LoginFailed + } + + property string password + + property var pamtester: Process { + property bool failed: true + + command: ["pamtester", "login", Quickshell.env("USER"), "authenticate"] + + onStarted: this.write(`${password}\n`) + + stdout: SplitParser { + // fails go to stderr + onRead: pamtester.failed = false + } + + onExited: { + if (failed) { + status = AuthContext.Status.LoginFailed + } else { + success(); + } + } + } + + function tryLogin(password: string) { + this.password = password + status = AuthContext.Status.Authenticating; + pamtester.running = true; + } +} diff --git a/modules/hyprland/lockscreen/Lockscreen.qml b/modules/hyprland/lockscreen/Lockscreen.qml new file mode 100644 index 0000000..76ac728 --- /dev/null +++ b/modules/hyprland/lockscreen/Lockscreen.qml @@ -0,0 +1,51 @@ +import QtQuick +import QtQuick.Controls.Universal + +Item { + required property AuthContext context + + Item { + anchors.centerIn: parent + scale: 2 + + TextField { + id: entryBox + anchors.centerIn: parent + width: 300 + + enabled: context.status != AuthContext.Status.Authenticating + focus: true + horizontalAlignment: TextInput.AlignHCenter + echoMode: TextInput.Password + inputMethodHints: Qt.ImhSensitiveData + placeholderText: "Enter password" + + onAccepted: { + if (text != "") context.tryLogin(text) + } + + onEnabledChanged: { + if (enabled) text = "" + } + } + + Text { + id: status + color: "white" + + anchors { + horizontalCenter: entryBox.horizontalCenter + top: entryBox.bottom + topMargin: 20 + } + + text: { + switch (context.status) { + case AuthContext.Status.FirstEntry: return "" + case AuthContext.Status.Authenticating: return "Authenticating" + case AuthContext.Status.LoginFailed: return "Login Failed" + } + } + } + } +} diff --git a/modules/hyprland/lockscreen/shell.qml b/modules/hyprland/lockscreen/shell.qml new file mode 100644 index 0000000..a30e6d0 --- /dev/null +++ b/modules/hyprland/lockscreen/shell.qml @@ -0,0 +1,32 @@ +import QtQuick +import QtQuick.Controls +import Quickshell +import Quickshell.Wayland + +ShellRoot { + AuthContext { + id: authContext + onSuccess: { + lock.locked = false; + Qt.quit() + } + } + + SessionLock { + id: lock + locked: true + + SessionLockSurface { + Image { + anchors.fill: parent + source: screen.name == "DP-1" ? "../5120x1440.png" : "../1920x1080.png" + } + + Lockscreen { + anchors.fill: parent + context: authContext + } + } + } + +} diff --git a/modules/hyprland/lockscreen/test.qml b/modules/hyprland/lockscreen/test.qml new file mode 100644 index 0000000..4710ae3 --- /dev/null +++ b/modules/hyprland/lockscreen/test.qml @@ -0,0 +1,21 @@ +import QtQuick +import Quickshell + +ShellRoot { + AuthContext { + id: authContext + onSuccess: Qt.quit() + } + + FloatingWindow { + Image { + anchors.fill: parent + source: "../1920x1080.png" + } + + Lockscreen { + anchors.fill: parent + context: authContext + } + } +}