Files
monoshell/Lock.qml

171 lines
5.4 KiB
QML

import Quickshell
import Quickshell.Wayland
import Quickshell.Widgets
import Quickshell.Io
import Quickshell.Services.Pam
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
WlSessionLock {
id: lock
locked: false
required property bool animate
function instalock() {lock.animate = false; lock.locked = true}
function open() {lock.animate = true; lock.locked = true}
function close() {lock.locked = false}
property var clock: SystemClock {}
WlSessionLockSurface {
id: surface
color: "transparent"
Rectangle {
id: content
anchors.fill: parent
opacity: !lock.animate || capture.ready
color: "#141414"
Rectangle {
anchors {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
bottomMargin: surface.height/6 - this.height/2
}
width: 300
height: 40
radius: height/2
color: "#222222"
TextInput {
id: input
anchors.fill: parent
focus: true
color: "white"
font.pixelSize: 20
echoMode: TextInput.NoEcho
cursorDelegate: Item {}
Keys.onReturnPressed: pam.start()
}
Row {
anchors.verticalCenter: parent.verticalCenter
x: (parent.width - this.width)/2
spacing: 4
Repeater {
model: input.text.length
Rectangle {
width: 8
height: width
radius: width/2
color: "white"
}
}
Behavior on x {
NumberAnimation {
duration: 300
easing.type: Easing.OutQuint
}
}
}
Text {
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.bottom
topMargin: 10
}
color: "white"
font.pixelSize: 14
text: pam.message
}
}
}
ClippingRectangle {
anchors.fill: parent
color: "white"
opacity: !lock.animate || capture.ready
radius: 0
RectangularShadow {
anchors.fill: parent
spread: 2
blur: 10
}
ScreencopyView {
id: capture
anchors.fill: parent
captureSource: surface.screen
readonly property bool ready: {
lock.animate &&
lock.secure &&
capture.hasContent
}
Connections {
target: lock
function onLockedChanged() {capture.captureFrame()}
}
}
transform: Scale {
origin { x: width/2; y: height/2 }
xScale: 1
yScale: xScale
NumberAnimation on xScale {
running: capture.ready
to: 0.80
duration: 800
easing.type: Easing.InQuint
}
NumberAnimation on xScale {
id: exit
running: false
from: 0.8
to: 1
duration: 800
easing.type: Easing.OutQuint
onStarted: {
capture.parent.visible = true
}
onFinished: lock.locked = false
}
}
SequentialAnimation on opacity {
running: capture.ready
PauseAnimation {duration: 500}
NumberAnimation {
duration: 300
to: 0
}
}
NumberAnimation on opacity {
duration: 300
running: exit.running
from: 0
to: 1
}
NumberAnimation on radius {
running: capture.ready
duration: 800
to: 32
}
NumberAnimation on radius {
running: exit.running
to: 0
duration: 800
}
}
PamContext {
id: pam
config: "pam.conf"
configDirectory: "."
onPamMessage: if (this.responseRequired) this.respond(input.text)
onCompleted: result => {
switch (result) {
case PamResult.Success:
exit.start()
break;
case PamResult.Failed:
case PamResult.Error:
case PamResult.MaxTries:
input.clear()
fail.start();
break;
}}
}
}
}