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

View file

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