summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-25 20:13:55 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-25 20:13:55 +1000
commit783057ab0d694de7f3d79e96851bcdcfe1965cbd (patch)
treeb70d2dc09e816ab6a4f3e6bf1b1fca148f258eed
parentreadme: fix confusing config statement (diff)
downloadcaelestia-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.md14
-rw-r--r--config/BackgroundConfig.qml8
-rw-r--r--config/DashboardConfig.qml1
-rw-r--r--config/ServiceConfig.qml1
-rw-r--r--modules/background/Background.qml33
-rw-r--r--modules/background/Visualiser.qml120
-rw-r--r--modules/dashboard/Media.qml6
-rw-r--r--modules/drawers/Drawers.qml2
-rw-r--r--services/Cava.qml8
-rw-r--r--services/Visibilities.qml1
10 files changed, 181 insertions, 13 deletions
diff --git a/README.md b/README.md
index 09a20ad..acca2c4 100644
--- a/README.md
+++ b/README.md
@@ -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);