This commit is contained in:
Ly-sec 2025-08-24 19:38:35 +02:00
parent 76626dc8da
commit 37dad3a255
4 changed files with 884 additions and 773 deletions

View file

@ -4,8 +4,8 @@ import Quickshell.Services.Pam
Scope {
id: root
signal unlocked()
signal failed()
signal unlocked
signal failed
property string currentText: ""
property bool unlockInProgress: false
@ -15,30 +15,30 @@ Scope {
onCurrentTextChanged: {
if (currentText !== "") {
showFailure = false;
errorMessage = "";
showFailure = false
errorMessage = ""
}
}
function tryUnlock() {
if (!pamAvailable) {
errorMessage = "PAM not available";
showFailure = true;
return;
errorMessage = "PAM not available"
showFailure = true
return
}
if (currentText === "") {
errorMessage = "Password required";
showFailure = true;
return;
errorMessage = "Password required"
showFailure = true
return
}
root.unlockInProgress = true;
errorMessage = "";
showFailure = false;
root.unlockInProgress = true
errorMessage = ""
showFailure = false
console.log("Starting PAM authentication for user:", pam.user);
pam.start();
console.log("Starting PAM authentication for user:", pam.user)
pam.start()
}
PamContext {
@ -47,46 +47,46 @@ Scope {
user: Quickshell.env("USER")
onPamMessage: {
console.log("PAM message:", message, "isError:", messageIsError, "responseRequired:", responseRequired);
console.log("PAM message:", message, "isError:", messageIsError, "responseRequired:", responseRequired)
if (messageIsError) {
errorMessage = message;
errorMessage = message
}
if (responseRequired) {
console.log("Responding to PAM with password");
respond(root.currentText);
console.log("Responding to PAM with password")
respond(root.currentText)
}
}
onResponseRequiredChanged: {
console.log("Response required changed:", responseRequired);
console.log("Response required changed:", responseRequired)
if (responseRequired && root.unlockInProgress) {
console.log("Automatically responding to PAM");
respond(root.currentText);
console.log("Automatically responding to PAM")
respond(root.currentText)
}
}
onCompleted: {
console.log("PAM completed with result:", result);
console.log("PAM completed with result:", result)
if (result === PamResult.Success) {
console.log("Authentication successful");
root.unlocked();
console.log("Authentication successful")
root.unlocked()
} else {
console.log("Authentication failed");
errorMessage = "Authentication failed";
showFailure = true;
root.failed();
console.log("Authentication failed")
errorMessage = "Authentication failed"
showFailure = true
root.failed()
}
root.unlockInProgress = false;
root.unlockInProgress = false
}
onError: {
console.log("PAM error:", error, "message:", message);
errorMessage = message || "Authentication error";
showFailure = true;
root.unlockInProgress = false;
root.failed();
console.log("PAM error:", error, "message:", message)
errorMessage = message || "Authentication error"
showFailure = true
root.unlockInProgress = false
root.failed()
}
}
}

View file

@ -60,22 +60,33 @@ Loader {
property bool batteryVisible: isReady && percent > 0
function getIcon() {
if (!batteryVisible) return ""
if (charging) return "battery_android_bolt"
if (percent >= 95) return "battery_android_full"
if (percent >= 85) return "battery_android_6"
if (percent >= 70) return "battery_android_5"
if (percent >= 55) return "battery_android_4"
if (percent >= 40) return "battery_android_3"
if (percent >= 25) return "battery_android_2"
if (percent >= 10) return "battery_android_1"
if (percent >= 0) return "battery_android_0"
if (!batteryVisible)
return ""
if (charging)
return "battery_android_bolt"
if (percent >= 95)
return "battery_android_full"
if (percent >= 85)
return "battery_android_6"
if (percent >= 70)
return "battery_android_5"
if (percent >= 55)
return "battery_android_4"
if (percent >= 40)
return "battery_android_3"
if (percent >= 25)
return "battery_android_2"
if (percent >= 10)
return "battery_android_1"
if (percent >= 0)
return "battery_android_0"
}
}
Item {
id: keyboardLayout
property string currentLayout: (typeof KeyboardLayoutService !== 'undefined' && KeyboardLayoutService.currentLayout) ? KeyboardLayoutService.currentLayout : "Unknown"
property string currentLayout: (typeof KeyboardLayoutService !== 'undefined'
&& KeyboardLayoutService.currentLayout) ? KeyboardLayoutService.currentLayout : "Unknown"
}
Image {
@ -99,10 +110,22 @@ Loader {
Rectangle {
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0.0; color: Qt.rgba(0, 0, 0, 0.6) }
GradientStop { position: 0.3; color: Qt.rgba(0, 0, 0, 0.3) }
GradientStop { position: 0.7; color: Qt.rgba(0, 0, 0, 0.4) }
GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.7) }
GradientStop {
position: 0.0
color: Qt.rgba(0, 0, 0, 0.6)
}
GradientStop {
position: 0.3
color: Qt.rgba(0, 0, 0, 0.3)
}
GradientStop {
position: 0.7
color: Qt.rgba(0, 0, 0, 0.4)
}
GradientStop {
position: 1.0
color: Qt.rgba(0, 0, 0, 0.7)
}
}
Repeater {
@ -117,8 +140,14 @@ Loader {
SequentialAnimation on opacity {
loops: Animation.Infinite
NumberAnimation { to: 0.8; duration: 2000 + Math.random() * 3000 }
NumberAnimation { to: 0.1; duration: 2000 + Math.random() * 3000 }
NumberAnimation {
to: 0.8
duration: 2000 + Math.random() * 3000
}
NumberAnimation {
to: 0.1
duration: 2000 + Math.random() * 3000
}
}
}
}
@ -150,8 +179,16 @@ Loader {
SequentialAnimation on scale {
loops: Animation.Infinite
NumberAnimation { to: 1.02; duration: 2000; easing.type: Easing.InOutQuad }
NumberAnimation { to: 1.0; duration: 2000; easing.type: Easing.InOutQuad }
NumberAnimation {
to: 1.02
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 1.0
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
@ -219,10 +256,12 @@ Loader {
Repeater {
model: CavaService.values.length * 2
Rectangle {
property int mirroredValueIndex: index < CavaService.values.length ? index : (CavaService.values.length * 2 - 1 - index)
property int mirroredValueIndex: index < CavaService.values.length ? index : (CavaService.values.length
* 2 - 1 - index)
property real mirroredAngle: (index / (CavaService.values.length * 2)) * 2 * Math.PI
property real mirroredRadius: 70 * scaling
property real mirroredBarLength: Math.max(2, CavaService.values[mirroredValueIndex] * 30 * scaling)
property real mirroredBarLength: Math.max(
2, CavaService.values[mirroredValueIndex] * 30 * scaling)
property real mirroredBarWidth: 3 * scaling
width: mirroredBarWidth
height: mirroredBarLength
@ -253,7 +292,8 @@ Loader {
onPaint: {
var ctx = getContext("2d")
ctx.reset()
if (CavaService.values.length === 0) return
if (CavaService.values.length === 0)
return
ctx.strokeStyle = Color.mPrimary
ctx.lineWidth = 2 * scaling
ctx.lineCap = "round"
@ -269,8 +309,10 @@ Loader {
var radius = baseRadius + amplitude
var x = centerX + Math.cos(angle) * radius
var y = centerY + Math.sin(angle) * radius
if (i === 0) ctx.moveTo(x, y)
else ctx.lineTo(x, y)
if (i === 0)
ctx.moveTo(x, y)
else
ctx.lineTo(x, y)
}
ctx.closePath()
ctx.stroke()
@ -297,8 +339,16 @@ Loader {
visible: !MediaService.isPlaying
SequentialAnimation on scale {
loops: Animation.Infinite
NumberAnimation { to: 1.1; duration: 1500; easing.type: Easing.InOutQuad }
NumberAnimation { to: 1.0; duration: 1500; easing.type: Easing.InOutQuad }
NumberAnimation {
to: 1.1
duration: 1500
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 1.0
duration: 1500
easing.type: Easing.InOutQuad
}
}
}
@ -318,7 +368,10 @@ Loader {
}
Behavior on scale {
NumberAnimation { duration: Style.animationFast; easing.type: Easing.OutBack }
NumberAnimation {
duration: Style.animationFast
easing.type: Easing.OutBack
}
}
}
}
@ -353,8 +406,14 @@ Loader {
opacity: Style.opacityMedium
SequentialAnimation on opacity {
loops: Animation.Infinite
NumberAnimation { to: 0.6; duration: 2000 + Math.random() * 1000 }
NumberAnimation { to: 0.1; duration: 2000 + Math.random() * 1000 }
NumberAnimation {
to: 0.6
duration: 2000 + Math.random() * 1000
}
NumberAnimation {
to: 0.1
duration: 2000 + Math.random() * 1000
}
}
}
}
@ -521,8 +580,18 @@ Loader {
SequentialAnimation {
id: typingEffect
NumberAnimation { target: passwordInput; property: "scale"; to: 1.01; duration: 50 }
NumberAnimation { target: passwordInput; property: "scale"; to: 1.0; duration: 50 }
NumberAnimation {
target: passwordInput
property: "scale"
to: 1.01
duration: 50
}
NumberAnimation {
target: passwordInput
property: "scale"
to: 1.0
duration: 50
}
}
}
@ -536,22 +605,33 @@ Loader {
SequentialAnimation on opacity {
loops: Animation.Infinite
NumberAnimation { to: 1.0; duration: 500 }
NumberAnimation { to: 0.0; duration: 500 }
NumberAnimation {
to: 1.0
duration: 500
}
NumberAnimation {
to: 0.0
duration: 500
}
}
}
}
NText {
text: {
if (lockContext.unlockInProgress) return "Authenticating..."
if (lockContext.showFailure && lockContext.errorMessage) return lockContext.errorMessage
if (lockContext.showFailure) return "Authentication failed."
if (lockContext.unlockInProgress)
return "Authenticating..."
if (lockContext.showFailure && lockContext.errorMessage)
return lockContext.errorMessage
if (lockContext.showFailure)
return "Authentication failed."
return ""
}
color: {
if (lockContext.unlockInProgress) return Color.mPrimary
if (lockContext.showFailure) return Color.mError
if (lockContext.unlockInProgress)
return Color.mPrimary
if (lockContext.showFailure)
return Color.mError
return Color.transparent
}
font.family: "DejaVu Sans Mono"
@ -561,8 +641,14 @@ Loader {
SequentialAnimation on opacity {
running: lockContext.unlockInProgress
loops: Animation.Infinite
NumberAnimation { to: 1.0; duration: 800 }
NumberAnimation { to: 0.5; duration: 800 }
NumberAnimation {
to: 1.0
duration: 800
}
NumberAnimation {
to: 0.5
duration: 800
}
}
}
@ -573,7 +659,8 @@ Loader {
width: 120 * scaling
height: 40 * scaling
radius: Style.radiusS * scaling
color: executeButtonArea.containsMouse ? Color.mPrimary : Color.applyOpacity(Color.mPrimary, "33")
color: executeButtonArea.containsMouse ? Color.mPrimary : Color.applyOpacity(Color.mPrimary,
"33")
border.color: Color.mPrimary
border.width: Math.max(1, Style.borderS * scaling)
enabled: !lockContext.unlockInProgress
@ -597,20 +684,36 @@ Loader {
SequentialAnimation on scale {
running: executeButtonArea.containsMouse
NumberAnimation { to: 1.05; duration: Style.animationFast; easing.type: Easing.OutCubic }
NumberAnimation {
to: 1.05
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
SequentialAnimation on scale {
running: !executeButtonArea.containsMouse
NumberAnimation { to: 1.0; duration: Style.animationFast; easing.type: Easing.OutCubic }
NumberAnimation {
to: 1.0
duration: Style.animationFast
easing.type: Easing.OutCubic
}
}
}
SequentialAnimation on scale {
loops: Animation.Infinite
running: lockContext.unlockInProgress
NumberAnimation { to: 1.02; duration: 600; easing.type: Easing.InOutQuad }
NumberAnimation { to: 1.0; duration: 600; easing.type: Easing.InOutQuad }
NumberAnimation {
to: 1.02
duration: 600
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 1.0
duration: 600
easing.type: Easing.InOutQuad
}
}
}
}
@ -626,8 +729,16 @@ Loader {
SequentialAnimation on opacity {
loops: Animation.Infinite
NumberAnimation { to: 0.6; duration: 2000; easing.type: Easing.InOutQuad }
NumberAnimation { to: 0.2; duration: 2000; easing.type: Easing.InOutQuad }
NumberAnimation {
to: 0.6
duration: 2000
easing.type: Easing.InOutQuad
}
NumberAnimation {
to: 0.2
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
}