forked from Shinonome/dots-hyprland
✨ feat(lock): add fingerprint support (#2308)
This commit is contained in:
@@ -28,7 +28,10 @@ Scope {
|
|||||||
Connections {
|
Connections {
|
||||||
target: GlobalStates
|
target: GlobalStates
|
||||||
function onScreenLockedChanged() {
|
function onScreenLockedChanged() {
|
||||||
if (GlobalStates.screenLocked) lockContext.reset();
|
if (GlobalStates.screenLocked) {
|
||||||
|
lockContext.reset();
|
||||||
|
lockContext.tryFingerUnlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import qs
|
|||||||
import qs.modules.common
|
import qs.modules.common
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
import Quickshell.Services.Pam
|
import Quickshell.Services.Pam
|
||||||
|
|
||||||
Scope {
|
Scope {
|
||||||
@@ -18,6 +19,7 @@ Scope {
|
|||||||
property string currentText: ""
|
property string currentText: ""
|
||||||
property bool unlockInProgress: false
|
property bool unlockInProgress: false
|
||||||
property bool showFailure: false
|
property bool showFailure: false
|
||||||
|
property bool fingerprintsConfigured: false
|
||||||
property var targetAction: LockContext.ActionEnum.Unlock
|
property var targetAction: LockContext.ActionEnum.Unlock
|
||||||
|
|
||||||
function resetTargetAction() {
|
function resetTargetAction() {
|
||||||
@@ -60,6 +62,34 @@ Scope {
|
|||||||
pam.start();
|
pam.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tryFingerUnlock() {
|
||||||
|
if (root.fingerprintsConfigured) {
|
||||||
|
fingerPam.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopFingerPam() {
|
||||||
|
fingerPam.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: fingerprintCheckProc
|
||||||
|
running: true
|
||||||
|
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 {
|
PamContext {
|
||||||
id: pam
|
id: pam
|
||||||
|
|
||||||
@@ -74,6 +104,7 @@ Scope {
|
|||||||
onCompleted: result => {
|
onCompleted: result => {
|
||||||
if (result == PamResult.Success) {
|
if (result == PamResult.Success) {
|
||||||
root.unlocked(root.targetAction);
|
root.unlocked(root.targetAction);
|
||||||
|
stopFingerPam();
|
||||||
} else {
|
} else {
|
||||||
root.clearText();
|
root.clearText();
|
||||||
root.unlockInProgress = false;
|
root.unlockInProgress = false;
|
||||||
@@ -83,4 +114,19 @@ Scope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PamContext {
|
||||||
|
id: fingerPam
|
||||||
|
|
||||||
|
configDirectory: "pam"
|
||||||
|
config: "fprintd.conf"
|
||||||
|
|
||||||
|
onCompleted: result => {
|
||||||
|
if (result == PamResult.Success) {
|
||||||
|
root.unlocked(root.targetAction);
|
||||||
|
stopFingerPam();
|
||||||
|
} else if (result == PamResult.Error){ // if timeout or etc..
|
||||||
|
tryFingerUnlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,23 @@ MouseArea {
|
|||||||
scale: root.toolbarScale
|
scale: root.toolbarScale
|
||||||
opacity: root.toolbarOpacity
|
opacity: root.toolbarOpacity
|
||||||
|
|
||||||
|
// Fingerprint
|
||||||
|
Loader {
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
Layout.rightMargin: 6
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
active: root.context.fingerprintsConfigured
|
||||||
|
visible: active
|
||||||
|
|
||||||
|
sourceComponent: MaterialSymbol {
|
||||||
|
id: fingerprintIcon
|
||||||
|
fill: 1
|
||||||
|
text: "fingerprint"
|
||||||
|
iconSize: Appearance.font.pixelSize.hugeass
|
||||||
|
color: Appearance.colors.colOnSurfaceVariant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ToolbarTextField {
|
ToolbarTextField {
|
||||||
id: passwordBox
|
id: passwordBox
|
||||||
placeholderText: GlobalStates.screenUnlockFailed ? Translation.tr("Incorrect password") : Translation.tr("Enter password")
|
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