lock: add placeholder + manual focus

This commit is contained in:
2 * r + 2 * t 2025-08-10 19:37:34 +10:00
parent 56ca1632c5
commit 31cc51b6e9
2 changed files with 104 additions and 58 deletions

View file

@ -110,6 +110,15 @@ ColumnLayout {
Keys.onPressed: event => root.lock.pam.handleKey(event)
StateLayer {
hoverEnabled: false
cursorShape: Qt.IBeamCursor
function onClicked(): void {
parent.forceActiveFocus();
}
}
RowLayout {
id: input
@ -122,58 +131,81 @@ ColumnLayout {
text: "lock"
}
ListView {
id: passwordList
Item {
Layout.fillWidth: true
implicitHeight: Appearance.font.size.normal
Layout.fillHeight: true
orientation: Qt.Horizontal
clip: true
spacing: Appearance.spacing.small / 2
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: 0
preferredHighlightEnd: count ? width - implicitHeight * 2 : 0
currentIndex: count - 1
ListView {
id: passwordList
model: ScriptModel {
values: root.lock.pam.buffer
}
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
implicitHeight: Appearance.font.size.normal
delegate: StyledRect {
implicitWidth: implicitHeight
implicitHeight: passwordList.implicitHeight
orientation: Qt.Horizontal
clip: true
interactive: false
spacing: Appearance.spacing.small / 2
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: 0
preferredHighlightEnd: count ? width - implicitHeight * 2 : 0
currentIndex: count - 1
color: Colours.palette.m3onSurface
radius: Appearance.rounding.small / 2
}
model: ScriptModel {
values: root.lock.pam.buffer
}
add: Transition {
Anim {
property: "scale"
from: 0
to: 1
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
delegate: StyledRect {
implicitWidth: implicitHeight
implicitHeight: passwordList.implicitHeight
color: Colours.palette.m3onSurface
radius: Appearance.rounding.small / 2
}
add: Transition {
Anim {
property: "scale"
from: 0
to: 1
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
}
}
remove: Transition {
Anim {
property: "scale"
to: 0.5
}
Anim {
property: "opacity"
to: 0
}
}
highlightFollowsCurrentItem: false
highlight: Item {
x: passwordList.currentItem?.x ?? 0
Behavior on x {
Anim {}
}
}
}
remove: Transition {
Anim {
property: "scale"
to: 0.5
}
Anim {
property: "opacity"
to: 0
}
}
StyledText {
anchors.centerIn: parent
highlightFollowsCurrentItem: false
highlight: Item {
x: passwordList.currentItem?.x ?? 0
text: qsTr("Enter your password")
color: Colours.palette.m3outline
font.pointSize: Appearance.font.size.normal
font.family: Appearance.font.family.mono
Behavior on x {
opacity: root.lock.pam.buffer ? 0 : 1
Behavior on opacity {
Anim {}
}
}

View file

@ -1,8 +1,9 @@
import Quickshell
import Quickshell.Wayland
import Quickshell.Services.Pam
import QtQuick
PamContext {
Scope {
id: root
required property WlSessionLock lock
@ -11,11 +12,11 @@ PamContext {
property string buffer: ""
function handleKey(event: KeyEvent): void {
if (active)
if (passwd.active)
return;
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
start();
passwd.start();
} else if (event.key === Qt.Key_Backspace) {
if (event.modifiers & Qt.ControlModifier) {
buffer = "";
@ -28,23 +29,36 @@ PamContext {
}
}
onResponseRequiredChanged: {
if (!responseRequired)
return;
PamContext {
id: passwd
respond(buffer);
buffer = "";
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)
root.state = "max";
else if (res === PamResult.Failed)
root.state = "fail";
stateReset.restart();
}
}
onCompleted: res => {
if (res === PamResult.Success)
return lock.unlock();
Timer {
id: stateReset
if (res === PamResult.Error)
state = "error";
else if (res === PamResult.MaxTries)
state = "max";
else if (res === PamResult.Failed)
state = "fail";
interval: 4000
onTriggered: root.state = "none"
}
}