forked from Shinonome/dots-hyprland
✨ feat(lock): add fingerprint support
Credit to @wooze-pao for providing the required code in #2162
This commit is contained in:
@@ -32,6 +32,16 @@ Scope {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onScreenLockedChanged() {
|
||||
if (GlobalStates.screenLocked) {
|
||||
lockContext.reset();
|
||||
lockContext.tryFingerUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onUnlocked: (targetAction) => {
|
||||
// Perform the target action if it's not just unlocking
|
||||
if (targetAction == LockContext.ActionEnum.Poweroff) {
|
||||
|
||||
@@ -2,6 +2,7 @@ import qs
|
||||
import qs.modules.common
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Pam
|
||||
|
||||
Scope {
|
||||
@@ -18,8 +19,13 @@ Scope {
|
||||
property string currentText: ""
|
||||
property bool unlockInProgress: false
|
||||
property bool showFailure: false
|
||||
property bool fingerprintsConfigured: false
|
||||
property var targetAction: LockContext.ActionEnum.Unlock
|
||||
|
||||
Component.onCompleted: {
|
||||
fingerprintCheckProcess.running = true;
|
||||
}
|
||||
|
||||
function resetTargetAction() {
|
||||
root.targetAction = LockContext.ActionEnum.Unlock;
|
||||
}
|
||||
@@ -37,6 +43,46 @@ Scope {
|
||||
root.clearText();
|
||||
root.unlockInProgress = false;
|
||||
}
|
||||
|
||||
function tryFingerUnlock() {
|
||||
fingerPam.start();
|
||||
}
|
||||
|
||||
function stopPam() {
|
||||
fingerPam.abort();
|
||||
}
|
||||
|
||||
Process {
|
||||
id: fingerprintCheckProcess
|
||||
command: ["bash", "-c", "fprintd-list $(whoami)"]
|
||||
stdout: StdioCollector {
|
||||
id: fingerprintOutputCollector
|
||||
onStreamFinished: {
|
||||
root.fingerprintsConfigured = fingerprintOutputCollector.text.includes("Fingerprints for user");
|
||||
}
|
||||
}
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("fprintd-list command exited with error:", exitCode, exitStatus);
|
||||
root.fingerprintsConfigured = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PamContext {
|
||||
id: fingerPam
|
||||
|
||||
configDirectory: "pam"
|
||||
config: "fprintd.conf"
|
||||
|
||||
onCompleted: result => {
|
||||
if (result == PamResult.Success) {
|
||||
root.unlocked(root.targetAction);
|
||||
} else if (result == PamResult.Error){ // if timeout or etc..
|
||||
tryFingerUnlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: passwordClearTimer
|
||||
|
||||
@@ -98,6 +98,28 @@ MouseArea {
|
||||
scale: root.toolbarScale
|
||||
opacity: root.toolbarOpacity
|
||||
|
||||
// Fingerprint
|
||||
Loader {
|
||||
Layout.leftMargin: 10
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
active: root.context.fingerprintsConfigured // Bind to actual fingerprint availability
|
||||
visible: root.context.fingerprintsConfigured
|
||||
|
||||
sourceComponent: Row {
|
||||
spacing: 8
|
||||
|
||||
MaterialSymbol {
|
||||
id: fingerprintIcon
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
fill: 1
|
||||
text: "fingerprint"
|
||||
iconSize: Appearance.font.pixelSize.huge
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
animateChange: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarTextField {
|
||||
id: passwordBox
|
||||
placeholderText: GlobalStates.screenUnlockFailed ? Translation.tr("Incorrect password") : Translation.tr("Enter password")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
auth sufficient pam_fprintd.so
|
||||
Reference in New Issue
Block a user