From 14d4d05acc235ab7033316d16530783c90e95faa Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 5 Sep 2025 23:31:35 +0200 Subject: ... --- .../gkleen@sif/shell/quickshell/LockSurface.qml | 223 +++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 accounts/gkleen@sif/shell/quickshell/LockSurface.qml (limited to 'accounts/gkleen@sif/shell/quickshell/LockSurface.qml') diff --git a/accounts/gkleen@sif/shell/quickshell/LockSurface.qml b/accounts/gkleen@sif/shell/quickshell/LockSurface.qml new file mode 100644 index 00000000..18698725 --- /dev/null +++ b/accounts/gkleen@sif/shell/quickshell/LockSurface.qml @@ -0,0 +1,223 @@ +import Quickshell.Widgets +import QtQuick.Effects +import QtQuick.Layouts +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.Fusion +import qs.Services +import QtQml + +Item { + id: lockSurface + + property var screen + property list messages: [] + property bool responseRequired: false + property bool responseVisible: false + property string currentText: "" + property bool authRunning: false + + signal response(string responseText) + + anchors.fill: parent + + Item { + id: background + + anchors.fill: parent + + property Img current: one + property string source: selector.selected + + WallpaperSelector { + id: selector + seed: lockSurface.screen?.name || "" + } + + onSourceChanged: { + if (!source) + current = null; + else if (current === one) + two.update() + else + one.update() + } + + Img { id: one } + Img { id: two } + + component Img: Item { + id: img + + property string source + + function update() { + source = background.source || "" + } + + anchors.fill: parent + + Image { + id: imageSource + + source: img.source + sourceSize: Qt.size(parent.width, parent.height) + fillMode: Image.PreserveAspectCrop + smooth: true + visible: false + asynchronous: true + cache: false + + onStatusChanged: { + if (status === Image.Ready) { + background.current = img + } + } + } + + MultiEffect { + id: imageEffect + + source: imageSource + anchors.fill: parent + blurEnabled: true + blur: 1 + blurMax: 64 + blurMultiplier: 2 + + opacity: 0 + + states: State { + name: "visible" + when: background.current === img + + PropertyChanges { + imageEffect.opacity: 1 + } + StateChangeScript { + name: "unloadOther" + script: { + if (img === one) + two.source = "" + if (img === two) + one.source = "" + } + } + } + + transitions: Transition { + SequentialAnimation { + NumberAnimation { + target: imageEffect + properties: "opacity" + duration: 5000 + easing.type: Easing.OutCubic + } + ScriptAction { + scriptName: "unloadOther" + } + } + } + } + } + } + + Item { + anchors { + top: lockSurface.top + left: lockSurface.left + right: lockSurface.right + } + + implicitWidth: lockSurface.width + implicitHeight: 21 + + Rectangle { + anchors.fill: parent + color: Qt.rgba(0, 0, 0, 0.75) + } + + Clock { + anchors.centerIn: parent + calendarPopup: false + } + } + + WrapperRectangle { + id: unlockUi + + Keys.onPressed: event => { + if (!lockSurface.authRunning) { + event.accepted = true; + lockSurface.authRunning = true; + } + } + focus: !passwordBox.visible + + visible: lockSurface.authRunning + + color: Qt.rgba(0, 0, 0, 0.75) + margin: 8 + + anchors.centerIn: parent + + ColumnLayout { + spacing: 4 + + BusyIndicator { + visible: running + running: !Array.from(lockSurface.messages).length && !lockSurface.responseRequired + } + + Repeater { + model: lockSurface.messages + + Text { + required property var modelData + + font.pointSize: 10 + font.family: "Fira Sans" + color: modelData.error ? "#f28a21" : "#ffffff" + + text: String(modelData.text).trim() + + Layout.fillWidth: true + horizontalAlignment: Text.AlignHCenter + } + } + + TextField { + id: passwordBox + + visible: lockSurface.responseRequired + echoMode: lockSurface.responseVisible ? TextInput.Normal : TextInput.Password + inputMethodHints: Qt.ImhSensitiveData + + onTextChanged: lockSurface.currentText = passwordBox.text + onAccepted: { + passwordBox.readOnly = true; + lockSurface.response(lockSurface.currentText); + } + + Connections { + target: lockSurface + function onCurrentTextChanged() { + passwordBox.text = lockSurface.currentText + } + } + Connections { + target: lockSurface + function onResponseRequiredChanged() { + if (lockSurface.responseRequired) + passwordBox.readOnly = false; + passwordBox.focus = true; + passwordBox.selectAll(); + } + } + + Layout.topMargin: 4 + Layout.fillWidth: true + } + } + } +} -- cgit v1.2.3