diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-08-25 20:13:55 +1000 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-08-25 20:13:55 +1000 |
| commit | 783057ab0d694de7f3d79e96851bcdcfe1965cbd (patch) | |
| tree | b70d2dc09e816ab6a4f3e6bf1b1fca148f258eed | |
| parent | readme: fix confusing config statement (diff) | |
| download | caelestia-shell-783057ab0d694de7f3d79e96851bcdcfe1965cbd.tar.gz caelestia-shell-783057ab0d694de7f3d79e96851bcdcfe1965cbd.tar.bz2 caelestia-shell-783057ab0d694de7f3d79e96851bcdcfe1965cbd.zip | |
background: add visualiser
Also dashboard.visualiserBars -> services.visualiserBars
| -rw-r--r-- | README.md | 14 | ||||
| -rw-r--r-- | config/BackgroundConfig.qml | 8 | ||||
| -rw-r--r-- | config/DashboardConfig.qml | 1 | ||||
| -rw-r--r-- | config/ServiceConfig.qml | 1 | ||||
| -rw-r--r-- | modules/background/Background.qml | 33 | ||||
| -rw-r--r-- | modules/background/Visualiser.qml | 120 | ||||
| -rw-r--r-- | modules/dashboard/Media.qml | 6 | ||||
| -rw-r--r-- | modules/drawers/Drawers.qml | 2 | ||||
| -rw-r--r-- | services/Cava.qml | 8 | ||||
| -rw-r--r-- | services/Visibilities.qml | 1 |
10 files changed, 181 insertions, 13 deletions
@@ -198,7 +198,13 @@ default, you must create it manually. "desktopClock": { "enabled": false }, - "enabled": true + "enabled": true, + "visualiser": { + "enabled": true, + "autoHide": true, + "rounding": 1, + "spacing": 1 + } }, "bar": { "dragThreshold": 20, @@ -277,8 +283,7 @@ default, you must create it manually. "enabled": true, "dragThreshold": 50, "mediaUpdateInterval": 500, - "showOnHover": true, - "visualiserBars": 45 + "showOnHover": true }, "launcher": { "actionPrefix": ">", @@ -324,7 +329,8 @@ default, you must create it manually. "weatherLocation": "", "useFahrenheit": false, "useTwelveHourClock": false, - "smartScheme": true + "smartScheme": true, + "visualiserBars": 45 }, "session": { "dragThreshold": 30, diff --git a/config/BackgroundConfig.qml b/config/BackgroundConfig.qml index 35e16d1..e901545 100644 --- a/config/BackgroundConfig.qml +++ b/config/BackgroundConfig.qml @@ -3,8 +3,16 @@ import Quickshell.Io JsonObject { property bool enabled: true property DesktopClock desktopClock: DesktopClock {} + property Visualiser visualiser: Visualiser {} component DesktopClock: JsonObject { property bool enabled: false } + + component Visualiser: JsonObject { + property bool enabled: true + property bool autoHide: true + property real rounding: 1 + property real spacing: 1 + } } diff --git a/config/DashboardConfig.qml b/config/DashboardConfig.qml index 26d2442..030292b 100644 --- a/config/DashboardConfig.qml +++ b/config/DashboardConfig.qml @@ -4,7 +4,6 @@ JsonObject { property bool enabled: true property bool showOnHover: true property int mediaUpdateInterval: 500 - property int visualiserBars: 45 property int dragThreshold: 50 property Sizes sizes: Sizes {} diff --git a/config/ServiceConfig.qml b/config/ServiceConfig.qml index cca554b..c8a49b3 100644 --- a/config/ServiceConfig.qml +++ b/config/ServiceConfig.qml @@ -6,6 +6,7 @@ JsonObject { property bool useFahrenheit: [Locale.ImperialUSSystem, Locale.ImperialSystem].includes(Qt.locale().measurementSystem) property bool useTwelveHourClock: Qt.locale().timeFormat(Locale.ShortFormat).toLowerCase().includes("a") property string gpuType: "" + property int visualiserBars: 45 property real audioIncrement: 0.1 property bool smartScheme: true property string defaultPlayer: "Spotify" diff --git a/modules/background/Background.qml b/modules/background/Background.qml index 3da8bf9..bdba570 100644 --- a/modules/background/Background.qml +++ b/modules/background/Background.qml @@ -1,4 +1,8 @@ +pragma ComponentBehavior: Bound + +import qs.components import qs.components.containers +import qs.services import qs.config import Quickshell import Quickshell.Wayland @@ -27,7 +31,34 @@ Loader { anchors.left: true anchors.right: true - Wallpaper {} + Wallpaper { + id: wallpaper + } + + Loader { + readonly property bool shouldBeActive: Config.background.visualiser.enabled && (!Config.background.visualiser.autoHide || Hypr.monitorFor(win.modelData).activeWorkspace.toplevels.values.every(t => t.lastIpcObject.floating)) ? 1 : 0 + property real offset: shouldBeActive ? 0 : win.modelData.height * 0.2 + + anchors.fill: parent + anchors.topMargin: offset + anchors.bottomMargin: -offset + opacity: shouldBeActive ? 1 : 0 + active: opacity > 0 + asynchronous: true + + sourceComponent: Visualiser { + screen: win.modelData + wallpaper: wallpaper + } + + Behavior on offset { + Anim {} + } + + Behavior on opacity { + Anim {} + } + } Loader { anchors.right: parent.right diff --git a/modules/background/Visualiser.qml b/modules/background/Visualiser.qml new file mode 100644 index 0000000..6dd0a12 --- /dev/null +++ b/modules/background/Visualiser.qml @@ -0,0 +1,120 @@ +pragma ComponentBehavior: Bound + +import qs.components +import qs.components.misc +import qs.services +import qs.config +import Quickshell +import Quickshell.Widgets +import QtQuick +import QtQuick.Effects + +Item { + id: root + + required property ShellScreen screen + required property Wallpaper wallpaper + + Ref { + service: Cava + } + + MultiEffect { + anchors.fill: parent + source: root.wallpaper + maskSource: wrapper + maskEnabled: true + blurEnabled: true + blur: 1 + blurMax: 32 + autoPaddingEnabled: false + } + + Item { + id: wrapper + + anchors.fill: parent + layer.enabled: true + + Item { + id: content + + anchors.fill: parent + anchors.margins: Config.border.thickness + anchors.leftMargin: Visibilities.bars.get(root.screen).exclusiveZone + Appearance.spacing.small * Config.background.visualiser.spacing + + Side {} + Side { + isRight: true + } + + Behavior on anchors.leftMargin { + Anim {} + } + } + } + + component Side: Repeater { + id: side + + property bool isRight + + model: Config.services.visualiserBars + + ClippingRectangle { + id: bar + + required property int modelData + property real value: Math.max(1, Math.min(100, Cava.values[side.isRight ? modelData : side.count - modelData - 1])) / 100 + + clip: true + + x: modelData * ((content.width * 0.4) / Config.services.visualiserBars) + (side.isRight ? content.width * 0.6 : 0) + implicitWidth: (content.width * 0.4) / Config.services.visualiserBars - Appearance.spacing.small * Config.background.visualiser.spacing + + y: content.height - height + implicitHeight: bar.value * content.height * 0.4 + + color: "transparent" + topLeftRadius: Appearance.rounding.small * Config.background.visualiser.rounding + topRightRadius: Appearance.rounding.small * Config.background.visualiser.rounding + + Rectangle { + topLeftRadius: parent.topLeftRadius + topRightRadius: parent.topRightRadius + + gradient: Gradient { + orientation: Gradient.Vertical + + GradientStop { + position: 0 + color: Qt.alpha(Colours.palette.m3primary, 0.7) + + Behavior on color { + CAnim {} + } + } + GradientStop { + position: 1 + color: Qt.alpha(Colours.palette.m3inversePrimary, 0.7) + + Behavior on color { + CAnim {} + } + } + } + + anchors.left: parent.left + anchors.right: parent.right + y: parent.height - height + implicitHeight: content.height * 0.4 + } + + Behavior on value { + Anim { + duration: Appearance.anim.durations.small + } + } + } + } +} diff --git a/modules/dashboard/Media.qml b/modules/dashboard/Media.qml index 9e61094..d2699a2 100644 --- a/modules/dashboard/Media.qml +++ b/modules/dashboard/Media.qml @@ -79,7 +79,7 @@ Item { id: visualiserBars model: Array.from({ - length: Config.dashboard.visualiserBars + length: Config.services.visualiserBars }, (_, i) => i) ShapePath { @@ -88,13 +88,13 @@ Item { required property int modelData readonly property int value: Math.max(1, Math.min(100, Cava.values[modelData])) - readonly property real angle: modelData * 2 * Math.PI / Config.dashboard.visualiserBars + readonly property real angle: modelData * 2 * Math.PI / Config.services.visualiserBars readonly property real magnitude: value / 100 * Config.dashboard.sizes.mediaVisualiserSize readonly property real cos: Math.cos(angle) readonly property real sin: Math.sin(angle) capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap - strokeWidth: 360 / Config.dashboard.visualiserBars - Appearance.spacing.small / 4 + strokeWidth: 360 / Config.services.visualiserBars - Appearance.spacing.small / 4 strokeColor: Colours.palette.m3primary startX: visualiser.centerX + (visualiser.innerX + strokeWidth / 2) * cos diff --git a/modules/drawers/Drawers.qml b/modules/drawers/Drawers.qml index b40eabe..648e280 100644 --- a/modules/drawers/Drawers.qml +++ b/modules/drawers/Drawers.qml @@ -139,6 +139,8 @@ Variants { screen: scope.modelData visibilities: visibilities popouts: panels.popouts + + Component.onCompleted: Visibilities.bars.set(scope.modelData, this) } } } diff --git a/services/Cava.qml b/services/Cava.qml index 9e5105e..f4d342a 100644 --- a/services/Cava.qml +++ b/services/Cava.qml @@ -8,14 +8,14 @@ import QtQuick Singleton { id: root - property list<int> values: Array(Config.dashboard.visualiserBars) + property list<int> values: Array(Config.services.visualiserBars) property int refCount Connections { - target: Config.dashboard + target: Config.services function onVisualiserBarsChanged() { - root.values = Array(Config.dashboard.visualiserBars); + root.values = Array(Config.services.visualiserBars); cavaProc.running = false; cavaProc.running = true; } @@ -25,7 +25,7 @@ Singleton { id: cavaProc running: true - command: ["sh", "-c", `printf '[general]\nframerate=60\nbars=${Config.dashboard.visualiserBars}\nsleep_timer=3\n[output]\nchannels=mono\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nascii_max_range=100\n[smoothing]\nnoise_reduction=85\nmonstercat=1\ngravity=120\n[eq]\n1=0.8\n2=0.9\n3=1\n4=1.1\n5=1.2' | cava -p /dev/stdin`] + command: ["sh", "-c", `printf '[general]\nframerate=60\nbars=${Config.services.visualiserBars}\nsleep_timer=3\n[output]\nchannels=mono\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nascii_max_range=100\n[smoothing]\nnoise_reduction=85\nmonstercat=1\ngravity=120\n[eq]\n1=0.8\n2=0.9\n3=1\n4=1.1\n5=1.2' | cava -p /dev/stdin`] stdout: SplitParser { onRead: data => { if (root.refCount) diff --git a/services/Visibilities.qml b/services/Visibilities.qml index 0f09e3a..5ddde0c 100644 --- a/services/Visibilities.qml +++ b/services/Visibilities.qml @@ -4,6 +4,7 @@ import Quickshell Singleton { property var screens: new Map() + property var bars: new Map() function load(screen: ShellScreen, visibilities: var): void { screens.set(Hypr.monitorFor(screen), visibilities); |