lock: nuke

This commit is contained in:
2 * r + 2 * t 2025-08-10 14:55:29 +10:00
parent fc6a088719
commit 5ca9dd373e
2 changed files with 130 additions and 146 deletions

View file

@ -6,52 +6,42 @@ import Quickshell.Io
import Quickshell.Wayland import Quickshell.Wayland
Scope { Scope {
LazyLoader {
id: loader
WlSessionLock { WlSessionLock {
id: lock id: lock
property bool unlocked signal unlock
locked: true LockSurface {
lock: lock
onLockedChanged: {
if (!locked)
loader.active = false;
}
LockSurface {
lock: lock
}
} }
} }
CustomShortcut { CustomShortcut {
name: "lock" name: "lock"
description: "Lock the current session" description: "Lock the current session"
onPressed: loader.activeAsync = true onPressed: lock.locked = true
} }
CustomShortcut { CustomShortcut {
name: "unlock" name: "unlock"
description: "Unlock the current session" description: "Unlock the current session"
onPressed: loader.item.locked = false onPressed: lock.unlock()
} }
IpcHandler { IpcHandler {
target: "lock" target: "lock"
function lock(): void { function lock(): void {
loader.activeAsync = true; lock.locked = true;
} }
function unlock(): void { function unlock(): void {
loader.item.locked = false; lock.unlock();
} }
function isLocked(): bool { function isLocked(): bool {
return loader.active; return lock.locked;
} }
} }
} }

View file

@ -1,5 +1,7 @@
pragma ComponentBehavior: Bound pragma ComponentBehavior: Bound
import qs.components
import qs.components.effects
import qs.services import qs.services
import qs.config import qs.config
import Quickshell.Wayland import Quickshell.Wayland
@ -11,30 +13,107 @@ WlSessionLockSurface {
required property WlSessionLock lock required property WlSessionLock lock
property bool thisLocked property bool locked
readonly property bool locked: thisLocked && !lock.unlocked
function unlock(): void { function unlock(): void {
lock.unlocked = true; lock.unlocked = true;
animDelay.start();
} }
Component.onCompleted: thisLocked = true Component.onCompleted: locked = true
color: "transparent" color: "transparent"
Timer {
id: animDelay
interval: Appearance.anim.durations.large
onTriggered: root.lock.locked = false
}
Connections { Connections {
target: root.lock target: root.lock
function onUnlockedChanged(): void { function onUnlock(): void {
background.opacity = 0; root.locked = false;
unlockAnim.start();
}
}
SequentialAnimation {
id: unlockAnim
ParallelAnimation {
Anim {
target: lockBg
properties: "implicitWidth,implicitHeight"
to: lockBg.size
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
}
Anim {
target: lockBg
property: "radius"
to: lockBg.size / 4
}
Anim {
targets: [background, lockBg]
property: "opacity"
to: 0
}
}
PropertyAction {
target: root.lock
property: "locked"
value: false
}
}
ParallelAnimation {
running: true
Anim {
target: background
property: "opacity"
to: 1
duration: Appearance.anim.durations.large
}
SequentialAnimation {
ParallelAnimation {
Anim {
target: lockBg
property: "scale"
to: 1
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial
}
Anim {
target: lockBg
property: "rotation"
to: 180
duration: Appearance.anim.durations.expressiveFastSpatial
easing.bezierCurve: Appearance.anim.curves.standardAccel
}
}
ParallelAnimation {
Anim {
target: lockIcon
property: "rotation"
to: 180
easing.bezierCurve: Appearance.anim.curves.standardDecel
}
Anim {
target: lockBg
property: "radius"
to: Appearance.rounding.large
}
Anim {
target: lockBg
property: "implicitWidth"
to: root.width * 0.8
duration: Appearance.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
Anim {
target: lockBg
property: "implicitHeight"
to: root.height * 0.8
duration: Appearance.anim.durations.expressiveDefaultSpatial
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
}
} }
} }
@ -43,138 +122,53 @@ WlSessionLockSurface {
anchors.fill: parent anchors.fill: parent
captureSource: root.screen captureSource: root.screen
opacity: 0
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
id: backgroundBlur
autoPaddingEnabled: false autoPaddingEnabled: false
blurEnabled: true blurEnabled: true
blur: root.locked ? 1 : 0 blur: 1
blurMax: 64 blurMax: 64
blurMultiplier: 1 blurMultiplier: 1
Behavior on blur {
Anim {}
}
}
Behavior on opacity {
Anim {}
} }
} }
Backgrounds { StyledRect {
id: backgrounds id: lockBg
locked: root.locked readonly property int size: lockIcon.implicitHeight + Appearance.padding.large * 4
weatherWidth: weather.implicitWidth
buttonsWidth: buttons.item?.nonAnimWidth ?? 0
buttonsHeight: buttons.item?.nonAnimHeight ?? 0
statusWidth: status.nonAnimWidth ?? 0
statusHeight: status.nonAnimHeight ?? 0
isNormal: root.screen.width > Config.lock.sizes.smallScreenWidth
isLarge: root.screen.width > Config.lock.sizes.largeScreenWidth
layer.enabled: true anchors.centerIn: parent
layer.effect: MultiEffect { implicitWidth: size
shadowEnabled: true implicitHeight: size
blurMax: 15
shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7) color: Colours.tPalette.m3surface
radius: size / 4
scale: 0
Elevation {
anchors.fill: parent
radius: parent.radius
z: -1
level: 3
offset.y: 0
} }
}
Clock { MaterialIcon {
anchors.horizontalCenter: parent.horizontalCenter id: lockIcon
anchors.bottom: parent.top
anchors.bottomMargin: -backgrounds.clockBottom
}
Input { anchors.centerIn: parent
anchors.horizontalCenter: parent.horizontalCenter text: "lock"
anchors.top: parent.bottom font.pointSize: Appearance.font.size.extraLarge * 4
anchors.topMargin: -backgrounds.inputTop font.bold: true
lock: root
}
WeatherInfo {
id: weather
anchors.top: parent.bottom
anchors.right: parent.left
anchors.topMargin: -backgrounds.weatherTop
anchors.rightMargin: -backgrounds.weatherRight
}
Loader {
id: media
active: root.screen.width > Config.lock.sizes.smallScreenWidth
asynchronous: true
state: root.screen.width > Config.lock.sizes.largeScreenWidth ? "tl" : "br"
states: [
State {
name: "tl"
AnchorChanges {
target: media
anchors.bottom: media.parent.top
anchors.right: media.parent.left
}
PropertyChanges {
media.anchors.bottomMargin: -backgrounds.mediaY
media.anchors.rightMargin: -backgrounds.mediaX
}
},
State {
name: "br"
AnchorChanges {
target: media
anchors.top: media.parent.bottom
anchors.left: media.parent.right
}
PropertyChanges {
media.anchors.topMargin: -backgrounds.mediaY
media.anchors.leftMargin: -backgrounds.mediaX
}
}
]
sourceComponent: MediaPlaying {
isLarge: root.screen.width > Config.lock.sizes.largeScreenWidth
} }
} }
Loader {
id: buttons
active: root.screen.width > Config.lock.sizes.largeScreenWidth
asynchronous: true
anchors.top: parent.bottom
anchors.left: parent.right
anchors.topMargin: -backgrounds.buttonsTop
anchors.leftMargin: -backgrounds.buttonsLeft
sourceComponent: Buttons {}
}
Status {
id: status
anchors.bottom: parent.top
anchors.left: parent.right
anchors.bottomMargin: -backgrounds.statusBottom
anchors.leftMargin: -backgrounds.statusLeft
showNotifs: root.screen.width > Config.lock.sizes.largeScreenWidth
}
component Anim: NumberAnimation { component Anim: NumberAnimation {
duration: Appearance.anim.durations.large duration: Appearance.anim.durations.normal
easing.type: Easing.BezierSpline easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard easing.bezierCurve: Appearance.anim.curves.standard
} }