Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/pam.d/howdy
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
auth required pam_howdy.so
2 changes: 1 addition & 1 deletion modules/lock/Center.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ColumnLayout {
id: root

required property var lock
readonly property real centerScale: Math.min(1, (lock.screen?.height ?? 1440) / 1440)
readonly property real centerScale: Math.min(1, (lock.screen ? lock.screen.height : 1440) / 1440)
readonly property int centerWidth: Tokens.sizes.lock.centerWidth * centerScale

Layout.preferredWidth: centerWidth
Expand Down
2 changes: 1 addition & 1 deletion modules/lock/Lock.qml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Scope {

Loader {
asynchronous: true
active: true
active: Quickshell.screens.length > 0
onLoaded: active = false

// Force a load of a screencopy so the one in the lock works
Expand Down
76 changes: 61 additions & 15 deletions modules/lock/Pam.qml
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,39 @@ Scope {

readonly property alias passwd: passwd
readonly property alias fprint: fprint
readonly property alias howdy: howdy

property string lockMessage
property string state
property string fprintState
property string buffer
property string fprintState: ""
property string buffer: ""

signal flashMsg

function handleKey(event: KeyEvent): void {
if (passwd.active || state === "max")
return;

if (howdy.active && event.key !== Qt.Key_Enter && event.key !== Qt.Key_Return) {
howdy.abort();
}

if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
passwd.start();
if (buffer.length === 0) {
if (howdy.available)
howdy.trigger();
} else {
if (howdy.active)
howdy.abort();
passwd.start();
}
} else if (event.key === Qt.Key_Backspace) {
if (event.modifiers & Qt.ControlModifier) {
buffer = "";
} else {
buffer = buffer.slice(0, -1);
}
} else if (/^[^\x00-\x1F\x7F-\x9F]+$/.test(event.text)) {
// Allow anything except control characters
buffer += event.text;
}
}
Expand All @@ -53,15 +65,13 @@ Scope {
onResponseRequiredChanged: {
if (!responseRequired)
return;

respond(root.buffer);
root.buffer = "";
}

onCompleted: res => {
if (res === PamResult.Success)
return root.lock.unlock();

if (res === PamResult.Error)
root.state = "error";
else if (res === PamResult.MaxTries)
Expand All @@ -77,9 +87,9 @@ Scope {
PamContext {
id: fprint

property bool available
property int tries
property int errorTries
property bool available: false
property int tries: 0
property int errorTries: 0

function checkAvail(): void {
if (!available || !GlobalConfig.lock.enableFprint || !root.lock.secure) {
Expand Down Expand Up @@ -110,11 +120,8 @@ Scope {
errorRetry.restart();
}
} else if (res === PamResult.MaxTries) {
// Isn't actually the real max tries as pam only reports completed
// when max tries is reached.
tries++;
if (tries < GlobalConfig.lock.maxFprintTries) {
// Restart if not actually real max tries
root.fprintState = "fail";
start();
} else {
Expand All @@ -128,27 +135,62 @@ Scope {
}
}

PamContext {
id: howdy

property bool available: false

function trigger(): void {
if (!available || !root.lock.secure)
return;
start();
}

config: "howdy"
configDirectory: Quickshell.shellDir + "/assets/pam.d"

onCompleted: res => {
if (res === PamResult.Success)
return root.lock.unlock();
else
abort();
}
}

Process {
id: availProc
id: fprintAvailProc

command: ["sh", "-c", "fprintd-list $USER"]
onExited: code => { // qmllint disable signal-handler-parameters

onExited: (code, exitStatus) => { // qmllint disable signal-handler-parameters
fprint.available = code === 0;
fprint.checkAvail();
}
}

Process {
id: howdyAvailProc

command: ["sh", "-c", "command -v howdy"]

onExited: (code, exitStatus) => { // qmllint disable signal-handler-parameters
howdy.available = code === 0;
}
}

Timer {
id: errorRetry

interval: 800

onTriggered: fprint.start()
}

Timer {
id: stateReset

interval: 4000

onTriggered: {
if (root.state !== "max")
root.state = "";
Expand All @@ -159,6 +201,7 @@ Scope {
id: fprintStateReset

interval: 4000

onTriggered: {
root.fprintState = "";
fprint.errorTries = 0;
Expand All @@ -168,7 +211,8 @@ Scope {
Connections {
function onSecureChanged(): void {
if (root.lock.secure) {
availProc.running = true;
fprintAvailProc.running = true;
howdyAvailProc.running = true;
root.buffer = "";
root.state = "";
root.fprintState = "";
Expand All @@ -178,6 +222,8 @@ Scope {

function onUnlock(): void {
fprint.abort();
howdy.abort();
passwd.abort();
}

target: root.lock
Expand Down
2 changes: 2 additions & 0 deletions modules/lock/center/InputField.qml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Item {
text: {
if (root.pam.passwd.active)
return qsTr("Loading...");
if (root.pam.howdy.active)
return qsTr("Scanning face...");
if (root.pam.state === "max")
return qsTr("Max tries reached");
return qsTr("Enter your password");
Expand Down
6 changes: 4 additions & 2 deletions modules/lock/center/PasswordInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ StyledRect {

AnimLoader {
anchors.centerIn: parent
anchors.verticalCenterOffset: sourceComponent === iconComp ? 1 : 0
sourceComp: root.lock.pam.passwd.active ? loadingComp : iconComp
anchors.verticalCenterOffset: sourceComp === iconComp ? 1 : 0
sourceComp: (root.lock.pam.passwd.active || root.lock.pam.howdy.active) ? loadingComp : iconComp
}

Component {
Expand All @@ -75,6 +75,8 @@ StyledRect {
MaterialIcon {
animate: true
text: {
if (root.lock.pam.howdy.active)
return "face";
if (root.lock.pam.fprint.tries >= GlobalConfig.lock.maxFprintTries)
return "fingerprint_off";
if (root.lock.pam.fprint.active)
Expand Down
10 changes: 5 additions & 5 deletions plugin/src/Caelestia/Blobs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
qml_module(caelestia-blobs
URI Caelestia.Blobs
SOURCES
blobgroup.cpp
blobshape.cpp
blobrect.cpp
blobinvertedrect.cpp
blobmaterial.cpp
blobgroup.hpp blobgroup.cpp
blobshape.hpp blobshape.cpp
blobrect.hpp blobrect.cpp
blobinvertedrect.hpp blobinvertedrect.cpp
blobmaterial.hpp blobmaterial.cpp
LIBRARIES
Qt::Quick
)
Expand Down
6 changes: 3 additions & 3 deletions plugin/src/Caelestia/Components/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
qml_module(caelestia-components
URI Caelestia.Components
SOURCES
lazylistview.cpp
wavyline.cpp
buttonrow.cpp
lazylistview.hpp lazylistview.cpp
wavyline.hpp wavyline.cpp
buttonrow.hpp buttonrow.cpp
LIBRARIES
Qt::Quick
)
22 changes: 11 additions & 11 deletions plugin/src/Caelestia/Config/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
qml_module(caelestia-config
URI Caelestia.Config
SOURCES
config.cpp
configattached.cpp
configobject.cpp
rootconfig.cpp
appearanceconfig.cpp
font.cpp
fontbuilder.cpp
tokens.cpp
tokensattached.cpp
anim.cpp
monitorconfigmanager.cpp
config.hpp config.cpp
configattached.hpp configattached.cpp
configobject.hpp configobject.cpp
rootconfig.hpp rootconfig.cpp
appearanceconfig.hpp appearanceconfig.cpp
font.hpp font.cpp
fontbuilder.hpp fontbuilder.cpp
tokens.hpp tokens.cpp
tokensattached.hpp tokensattached.cpp
anim.hpp anim.cpp
monitorconfigmanager.hpp monitorconfigmanager.cpp
backgroundconfig.hpp
barconfig.hpp
borderconfig.hpp
Expand Down
6 changes: 3 additions & 3 deletions plugin/src/Caelestia/Images/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
qml_module(caelestia-images
URI Caelestia.Images
SOURCES
cachingimageprovider.cpp
imagecacher.cpp
iutils.cpp
cachingimageprovider.hpp cachingimageprovider.cpp
imagecacher.hpp imagecacher.cpp
iutils.hpp iutils.cpp
LIBRARIES
Qt::Gui
Qt::Quick
Expand Down
16 changes: 8 additions & 8 deletions plugin/src/Caelestia/Internal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
qml_module(caelestia-internal
URI Caelestia.Internal
SOURCES
circularbuffer.cpp
circularindicatormanager.cpp
linearindicatormanager.cpp
hyprdevices.cpp
hyprextras.cpp
logindmanager.cpp
sparklineitem.cpp
visualiserbars.cpp
circularbuffer.hpp circularbuffer.cpp
circularindicatormanager.hpp circularindicatormanager.cpp
linearindicatormanager.hpp linearindicatormanager.cpp
hyprdevices.hpp hyprdevices.cpp
hyprextras.hpp hyprextras.cpp
logindmanager.hpp logindmanager.cpp
sparklineitem.hpp sparklineitem.cpp
visualiserbars.hpp visualiserbars.cpp
LIBRARIES
Qt::Gui
Qt::Quick
Expand Down
32 changes: 16 additions & 16 deletions plugin/src/Caelestia/Services/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
qml_module(caelestia-services
URI Caelestia.Services
SOURCES
service.cpp
serviceref.cpp
beattracker.cpp
audiocollector.cpp
audioprovider.cpp
cavaprovider.cpp
tickingservice.cpp
sensorslib.cpp
usagefmt.cpp
cpu.cpp
gpu.cpp
memory.cpp
diskinfo.cpp
storage.cpp
lyriccandidate.cpp
lyrics.cpp
service.hpp service.cpp
serviceref.hpp serviceref.cpp
beattracker.hpp beattracker.cpp
audiocollector.hpp audiocollector.cpp
audioprovider.hpp audioprovider.cpp
cavaprovider.hpp cavaprovider.cpp
tickingservice.hpp tickingservice.cpp
sensorslib.hpp sensorslib.cpp
usagefmt.hpp usagefmt.cpp
cpu.hpp cpu.cpp
gpu.hpp gpu.cpp
memory.hpp memory.cpp
diskinfo.hpp diskinfo.cpp
storage.hpp storage.cpp
lyriccandidate.hpp lyriccandidate.cpp
lyrics.hpp lyrics.cpp
LIBRARIES
PkgConfig::Pipewire
PkgConfig::Aubio
Expand Down