pragma ComponentBehavior: Bound import Quickshell.Wayland import QtQuick import QtQuick.Effects import ZShell.Config import qs.Helpers import qs.Components import qs.Services WlSessionLockSurface { id: root required property WlSessionLock lock required property Pam pam readonly property alias unlocking: unlockAnim.running color: "transparent" Connections { function onUnlock(): void { unlockAnim.start(); } target: root.lock } SequentialAnimation { id: unlockAnim ParallelAnimation { Anim { duration: Tokens.anim.durations.expressiveDefaultSpatial easing: Tokens.anim.expressiveDefaultSpatial properties: "implicitWidth,implicitHeight" target: lockContent to: lockContent.size } Anim { property: "radius" target: lockBg to: lockContent.radius } Anim { duration: Tokens.anim.durations.expressiveDefaultSpatial easing: Tokens.anim.expressiveDefaultSpatial property: "scale" target: content to: 0 } Anim { duration: Tokens.anim.durations.small property: "opacity" target: content to: 0 } Anim { duration: Tokens.anim.durations.large property: "opacity" target: lockIcon to: 1 } SequentialAnimation { PauseAnimation { duration: Tokens.anim.durations.small } Anim { property: "opacity" target: lockContent to: 0 } } } PropertyAction { property: "locked" target: root.lock value: false } } ParallelAnimation { id: initAnim running: true SequentialAnimation { ParallelAnimation { Anim { duration: Tokens.anim.durations.expressiveFastSpatial easing: Tokens.anim.expressiveFastSpatial property: "scale" target: lockContent to: 1 } } ParallelAnimation { Anim { property: "opacity" target: lockIcon to: 0 } Anim { property: "opacity" target: content to: 1 } Anim { duration: Tokens.anim.durations.expressiveDefaultSpatial easing: Tokens.anim.expressiveDefaultSpatial property: "scale" target: content to: 1 } Anim { property: "radius" target: lockBg to: Tokens.rounding.largeIncreased * 1.5 } Anim { duration: Tokens.anim.durations.expressiveDefaultSpatial easing: Tokens.anim.expressiveDefaultSpatial property: "implicitWidth" target: lockContent to: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio } Anim { duration: Tokens.anim.durations.expressiveDefaultSpatial easing: Tokens.anim.expressiveDefaultSpatial property: "implicitHeight" target: lockContent to: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult } } } } Image { id: background anchors.bottomMargin: -8 - lockContent.positions[lockContent.positionIndex].y anchors.fill: parent anchors.leftMargin: -8 + lockContent.positions[lockContent.positionIndex].x anchors.rightMargin: -8 - lockContent.positions[lockContent.positionIndex].x anchors.topMargin: -8 + lockContent.positions[lockContent.positionIndex].y fillMode: Image.PreserveAspectCrop source: WallpaperPath.lockscreenBg Behavior on anchors.bottomMargin { Anim { duration: 5000 } } Behavior on anchors.leftMargin { Anim { duration: 5000 } } Behavior on anchors.rightMargin { Anim { duration: 5000 } } Behavior on anchors.topMargin { Anim { duration: 5000 } } } Item { id: lockContent property int positionIndex: 0 readonly property var positions: [Qt.point(0, 0), Qt.point(4, 0), Qt.point(4, 4), Qt.point(0, 4), Qt.point(-4, 4), Qt.point(-4, 0), Qt.point(-4, -4), Qt.point(0, -4), Qt.point(4, -4),] readonly property int radius: size / 4 * Tokens.rounding.scale readonly property int size: lockIcon.implicitHeight + Tokens.padding.large * 4 anchors.centerIn: parent anchors.horizontalCenterOffset: positions[positionIndex].x anchors.verticalCenterOffset: positions[positionIndex].y implicitHeight: size implicitWidth: size scale: 0 Behavior on anchors.horizontalCenterOffset { Anim { duration: 5000 } } Behavior on anchors.verticalCenterOffset { Anim { duration: 5000 } } Timer { interval: 120000 repeat: true running: true onTriggered: { lockContent.positionIndex = (lockContent.positionIndex + 1) % lockContent.positions.length; } } CustomRect { id: lockBg anchors.fill: parent color: Colors.palette.m3surface layer.enabled: true opacity: Colors.transparency.enabled ? Colors.transparency.base : 1 radius: lockContent.radius layer.effect: MultiEffect { blurMax: 15 shadowColor: Qt.alpha(Colors.palette.m3shadow, 0.7) shadowEnabled: true } } MaterialIcon { id: lockIcon anchors.centerIn: parent font.bold: true font.pointSize: Tokens.font.size.extraLarge * 4 text: "lock" } Content { id: content anchors.centerIn: parent height: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult - Tokens.padding.large * 2 lock: root opacity: 0 scale: 0 width: (root.screen?.height ?? 0) * Config.lock.sizes.heightMult * Config.lock.sizes.ratio - Tokens.padding.large * 2 } } }