From ed19b7b63529a2a70bfad2acc87b51aeb50a450b Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sun, 14 Sep 2025 22:53:55 +0200 Subject: [PATCH] lock screen: blur effect, better anims --- .../ii/modules/background/Background.qml | 80 +++++++++++++++---- .../quickshell/ii/modules/common/Config.qml | 7 ++ .config/quickshell/ii/modules/lock/Lock.qml | 27 +++---- 3 files changed, 83 insertions(+), 31 deletions(-) diff --git a/.config/quickshell/ii/modules/background/Background.qml b/.config/quickshell/ii/modules/background/Background.qml index e277fda3f..f39995978 100644 --- a/.config/quickshell/ii/modules/background/Background.qml +++ b/.config/quickshell/ii/modules/background/Background.qml @@ -7,6 +7,7 @@ import qs.modules.common.widgets import qs.modules.common.functions as CF import QtQuick import QtQuick.Layouts +import Qt5Compat.GraphicalEffects import Quickshell import Quickshell.Io import Quickshell.Wayland @@ -53,19 +54,27 @@ Variants { property real movableYSpace: ((wallpaperHeight / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.height) / 2 readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical // Position - property real clockX: (modelData.width / 2) + ((Math.random() < 0.5 ? -1 : 1) * modelData.width) - property real clockY: (modelData.height / 2) + ((Math.random() < 0.5 ? -1 : 1) * modelData.height) - property var textHorizontalAlignment: clockX < screen.width / 3 ? Text.AlignLeft : - (clockX > screen.width * 2 / 3 ? Text.AlignRight : Text.AlignHCenter) + property real clockX: (modelData.width / 2) + property real clockY: (modelData.height / 2) + property var textHorizontalAlignment: { + if (Config.options.background.blur.enable && Config.options.background.blur.centerClock && GlobalStates.screenLocked) + return Text.AlignHCenter; + if (clockX < screen.width / 3) + return Text.AlignLeft; + if (clockX > screen.width * 2 / 3) + return Text.AlignRight; + return Text.AlignHCenter; + } // Colors property color dominantColor: Appearance.colors.colPrimary property bool dominantColorIsDark: dominantColor.hslLightness < 0.5 property color colText: CF.ColorUtils.colorWithLightness(Appearance.colors.colPrimary, (dominantColorIsDark ? 0.8 : 0.12)) + property bool shouldBlur: (GlobalStates.screenLocked && Config.options.background.blur.enable) // Layer props screen: modelData exclusionMode: ExclusionMode.Ignore - WlrLayershell.layer: GlobalStates.screenLocked ? WlrLayer.Overlay : WlrLayer.Bottom + WlrLayershell.layer: (GlobalStates.screenLocked && !scaleAnim.running) ? WlrLayer.Overlay : WlrLayer.Bottom // WlrLayershell.layer: WlrLayer.Bottom WlrLayershell.namespace: "quickshell:background" anchors { @@ -214,14 +223,31 @@ Variants { } width: bgRoot.wallpaperWidth / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale height: bgRoot.wallpaperHeight / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale - // scale: GlobalStates.screenLocked ? 1.04 : 1 - // Behavior on scale { - // NumberAnimation { - // duration: 400 - // easing.type: Easing.BezierSpline - // easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial - // } - // } + } + + Loader { + id: blurLoader + active: Config.options.background.blur.enable && (GlobalStates.screenLocked || scaleAnim.running) + anchors.fill: wallpaper + scale: GlobalStates.screenLocked ? Config.options.background.blur.extraZoom : 1 + Behavior on scale { + NumberAnimation { + id: scaleAnim + duration: 400 + easing.type: Easing.BezierSpline + easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial + } + } + sourceComponent: GaussianBlur { + source: wallpaper + radius: GlobalStates.screenLocked ? Config.options.background.blur.radius : 0 + samples: radius * 2 + 1 + + Rectangle { + anchors.fill: parent + color: CF.ColorUtils.transparentize(Appearance.colors.colLayer0, 0.7) + } + } } // The clock @@ -231,8 +257,13 @@ Variants { anchors { left: wallpaper.left top: wallpaper.top + horizontalCenter: undefined leftMargin: bgRoot.movableXSpace + ((root.fixedClockPosition ? root.fixedClockX : bgRoot.clockX * bgRoot.effectiveWallpaperScale) - implicitWidth / 2) - topMargin: bgRoot.movableYSpace + ((root.fixedClockPosition ? root.fixedClockY : bgRoot.clockY * bgRoot.effectiveWallpaperScale) - implicitHeight / 2) + topMargin: { + if (bgRoot.shouldBlur) + return bgRoot.modelData.height / 3 + return bgRoot.movableYSpace + ((root.fixedClockPosition ? root.fixedClockY : bgRoot.clockY * bgRoot.effectiveWallpaperScale) - implicitHeight / 2) + } Behavior on leftMargin { animation: Appearance.animation.elementMove.numberAnimation.createObject(this) } @@ -240,6 +271,25 @@ Variants { animation: Appearance.animation.elementMove.numberAnimation.createObject(this) } } + states: State { + name: "centered" + when: bgRoot.shouldBlur + AnchorChanges { + target: clockLoader + anchors { + left: undefined + horizontalCenter: wallpaper.horizontalCenter + right: undefined + } + } + } + transitions: Transition { + AnchorAnimation { + duration: Appearance.animation.elementMove.duration + easing.type: Appearance.animation.elementMove.type + easing.bezierCurve: Appearance.animation.elementMove.bezierCurve + } + } sourceComponent: Item { id: clock implicitWidth: clockColumn.implicitWidth @@ -304,7 +354,7 @@ Variants { leftMargin: -5 rightMargin: -5 } - opacity: GlobalStates.screenLocked ? 1 : 0 + opacity: GlobalStates.screenLocked && (!Config.options.background.blur.enable || Config.options.background.blur.showLockedText) ? 1 : 0 visible: opacity > 0 Behavior on opacity { animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) diff --git a/.config/quickshell/ii/modules/common/Config.qml b/.config/quickshell/ii/modules/common/Config.qml index d60dc6e53..dd4d8f21c 100644 --- a/.config/quickshell/ii/modules/common/Config.qml +++ b/.config/quickshell/ii/modules/common/Config.qml @@ -135,6 +135,13 @@ Singleton { property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size property bool enableSidebar: true } + property JsonObject blur: JsonObject { + property bool enable: true + property int radius: 100 + property bool centerClock: true + property bool showLockedText: true + property real extraZoom: 1.1 + } property string quote: "" property bool hideWhenFullscreen: true } diff --git a/.config/quickshell/ii/modules/lock/Lock.qml b/.config/quickshell/ii/modules/lock/Lock.qml index 2024c19b2..1acaa19e4 100644 --- a/.config/quickshell/ii/modules/lock/Lock.qml +++ b/.config/quickshell/ii/modules/lock/Lock.qml @@ -48,23 +48,18 @@ Scope { // Blur layer hack Variants { model: Quickshell.screens - - LazyLoader { - id: blurLayerLoader - required property var modelData - active: GlobalStates.screenLocked - component: PanelWindow { - screen: blurLayerLoader.modelData - WlrLayershell.namespace: "quickshell:lockWindowPusher" - color: "transparent" - anchors { - top: true - left: true - right: true + delegate: Scope { + required property ShellScreen modelData + property bool shouldPush: GlobalStates.screenLocked + property string targetMonitorName: modelData.name + property int verticalMovementDistance: modelData.height + property int horizontalSqueeze: modelData.width * 0.2 + onShouldPushChanged: { + if (shouldPush) { + Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, ${verticalMovementDistance}, ${-verticalMovementDistance}, ${horizontalSqueeze}, ${horizontalSqueeze}`]) + } else { + Quickshell.execDetached(["bash", "-c", `hyprctl keyword monitor ${targetMonitorName}, addreserved, 0, 0, 0, 0`]) } - // implicitHeight: lockContext.currentText == "" ? 1 : screen.height - implicitHeight: 1 - exclusiveZone: screen.height * 3 // For some reason if we don't multiply by some number it would look really weird } } }