summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-14 16:25:46 +1000
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-08-14 16:25:46 +1000
commit04ce9ccbb4a1b4ee8ee1850f90af886412852b9f (patch)
treeaa2ebf44dc59b5bb56c6c0fd9557f7e82e71d1d4
parentnix: extend `hm-module` for CLI config options and add `extraRuntimeDeps` to ... (diff)
downloadcaelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.tar.gz
caelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.tar.bz2
caelestia-shell-04ce9ccbb4a1b4ee8ee1850f90af886412852b9f.zip
internal: better colourisation
-rw-r--r--components/effects/ColouredIcon.qml83
-rw-r--r--components/effects/Colouriser.qml4
-rw-r--r--modules/bar/components/OsIcon.qml11
-rw-r--r--modules/bar/components/workspaces/ActiveIndicator.qml1
-rw-r--r--modules/dashboard/dash/User.qml9
-rw-r--r--modules/lock/Fetch.qml10
-rw-r--r--modules/lock/NotifGroup.qml16
-rw-r--r--modules/notifications/Notification.qml8
8 files changed, 100 insertions, 42 deletions
diff --git a/components/effects/ColouredIcon.qml b/components/effects/ColouredIcon.qml
new file mode 100644
index 0000000..8ba6c5d
--- /dev/null
+++ b/components/effects/ColouredIcon.qml
@@ -0,0 +1,83 @@
+pragma ComponentBehavior: Bound
+
+import Quickshell.Widgets
+import QtQuick
+
+IconImage {
+ id: root
+
+ required property color colour
+ property color sourceColour
+ property url lastSource
+
+ asynchronous: true
+
+ layer.enabled: true
+ layer.effect: Colouriser {
+ sourceColor: root.sourceColour
+ colorizationColor: root.colour
+ }
+
+ layer.onEnabledChanged: {
+ if (layer.enabled)
+ canvas.requestPaint();
+ }
+
+ onStatusChanged: {
+ if (layer.enabled && status === Image.Ready)
+ canvas.requestPaint();
+ }
+
+ Canvas {
+ id: canvas
+
+ property int retryCount
+
+ implicitWidth: 32
+ implicitHeight: 32
+ visible: false
+
+ onPaint: {
+ if (!root.layer.enabled)
+ return;
+
+ const ctx = getContext("2d");
+ ctx.reset();
+ ctx.drawImage(root.backer, 0, 0, width, height);
+
+ const colours = {} as Object;
+ const data = ctx.getImageData(0, 0, width, height).data;
+
+ for (let i = 0; i < data.length; i += 4) {
+ if (data[i + 3] === 0)
+ continue;
+
+ const c = `${data[i]},${data[i + 1]},${data[i + 2]}`;
+ if (colours.hasOwnProperty(c))
+ colours[c]++;
+ else
+ colours[c] = 1;
+ }
+
+ // Canvas is empty, try again next frame
+ if (retryCount < 5 && !Object.keys(colours).length) {
+ retryCount++;
+ Qt.callLater(() => requestPaint());
+ return;
+ }
+
+ let max = 0;
+ let maxColour = "0,0,0";
+ for (const [colour, occurences] of Object.entries(colours)) {
+ if (occurences > max) {
+ max = occurences;
+ maxColour = colour;
+ }
+ }
+
+ const [r, g, b] = maxColour.split(",");
+ root.sourceColour = Qt.rgba(r / 255, g / 255, b / 255, 1);
+ retryCount = 0;
+ }
+ }
+}
diff --git a/components/effects/Colouriser.qml b/components/effects/Colouriser.qml
index b621ecd..bddf573 100644
--- a/components/effects/Colouriser.qml
+++ b/components/effects/Colouriser.qml
@@ -3,8 +3,10 @@ import QtQuick
import QtQuick.Effects
MultiEffect {
+ property color sourceColor: "black"
+
colorization: 1
- brightness: colorizationColor.hslLightness
+ brightness: 1 - sourceColor.hslLightness
Behavior on colorizationColor {
ColorAnimation {
diff --git a/modules/bar/components/OsIcon.qml b/modules/bar/components/OsIcon.qml
index 8418902..ed6da5d 100644
--- a/modules/bar/components/OsIcon.qml
+++ b/modules/bar/components/OsIcon.qml
@@ -1,15 +1,10 @@
import qs.components.effects
import qs.services
-import qs.utils
import qs.config
-import Quickshell.Widgets
+import qs.utils
-IconImage {
+ColouredIcon {
source: SysInfo.osLogo
implicitSize: Appearance.font.size.large * 1.2
-
- layer.enabled: true
- layer.effect: Colouriser {
- colorizationColor: Colours.palette.m3tertiary
- }
+ colour: Colours.palette.m3tertiary
}
diff --git a/modules/bar/components/workspaces/ActiveIndicator.qml b/modules/bar/components/workspaces/ActiveIndicator.qml
index b18cac2..3167d6e 100644
--- a/modules/bar/components/workspaces/ActiveIndicator.qml
+++ b/modules/bar/components/workspaces/ActiveIndicator.qml
@@ -51,6 +51,7 @@ StyledRect {
Colouriser {
source: root.mask
+ sourceColor: Colours.palette.m3onSurface
colorizationColor: Colours.palette.m3onPrimary
x: 0
diff --git a/modules/dashboard/dash/User.qml b/modules/dashboard/dash/User.qml
index e45153e..ffdc72a 100644
--- a/modules/dashboard/dash/User.qml
+++ b/modules/dashboard/dash/User.qml
@@ -5,7 +5,6 @@ import qs.services
import qs.config
import qs.utils
import Quickshell
-import Quickshell.Widgets
import QtQuick
Row {
@@ -119,7 +118,7 @@ Row {
implicitWidth: icon.implicitWidth + text.width + text.anchors.leftMargin
implicitHeight: Math.max(icon.implicitHeight, text.implicitHeight)
- IconImage {
+ ColouredIcon {
id: icon
anchors.left: parent.left
@@ -127,11 +126,7 @@ Row {
source: SysInfo.osLogo
implicitSize: Math.floor(Appearance.font.size.normal * 1.34)
-
- layer.enabled: true
- layer.effect: Colouriser {
- colorizationColor: Colours.palette.m3primary
- }
+ colour: Colours.palette.m3primary
}
StyledText {
diff --git a/modules/lock/Fetch.qml b/modules/lock/Fetch.qml
index ce64c8c..8f82e88 100644
--- a/modules/lock/Fetch.qml
+++ b/modules/lock/Fetch.qml
@@ -1,12 +1,10 @@
pragma ComponentBehavior: Bound
import qs.components
-import qs.components.widgets
import qs.components.effects
import qs.services
import qs.config
import qs.utils
-import Quickshell.Widgets
import Quickshell.Services.UPower
import QtQuick
import QtQuick.Layouts
@@ -149,15 +147,11 @@ ColumnLayout {
visible: active
}
- component OsLogo: IconImage {
+ component OsLogo: ColouredIcon {
source: SysInfo.osLogo
implicitSize: height
- asynchronous: true
-
+ colour: Colours.palette.m3primary
layer.enabled: Config.lock.recolourLogo || SysInfo.isDefaultLogo
- layer.effect: Colouriser {
- colorizationColor: Colours.palette.m3primary
- }
}
component FetchText: MonoText {
diff --git a/modules/lock/NotifGroup.qml b/modules/lock/NotifGroup.qml
index b119503..9af3947 100644
--- a/modules/lock/NotifGroup.qml
+++ b/modules/lock/NotifGroup.qml
@@ -62,15 +62,11 @@ StyledRect {
Component {
id: appIconComp
- IconImage {
+ ColouredIcon {
implicitSize: Math.round(Config.notifs.sizes.image * 0.6)
source: Quickshell.iconPath(root.appIcon)
- asynchronous: true
-
+ colour: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
layer.enabled: root.appIcon.endsWith("symbolic")
- layer.effect: Colouriser {
- colorizationColor: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
- }
}
}
@@ -109,16 +105,12 @@ StyledRect {
color: root.urgency === "critical" ? Colours.palette.m3error : root.urgency === "low" ? Colours.palette.m3surfaceContainerHighest : Colours.palette.m3secondaryContainer
radius: Appearance.rounding.full
- IconImage {
+ ColouredIcon {
anchors.centerIn: parent
implicitSize: Math.round(Config.notifs.sizes.badge * 0.6)
source: Quickshell.iconPath(root.appIcon)
- asynchronous: true
-
+ colour: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
layer.enabled: root.appIcon.endsWith("symbolic")
- layer.effect: Colouriser {
- colorizationColor: root.urgency === "critical" ? Colours.palette.m3onError : root.urgency === "low" ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
- }
}
}
}
diff --git a/modules/notifications/Notification.qml b/modules/notifications/Notification.qml
index 73bfce2..d1426fa 100644
--- a/modules/notifications/Notification.qml
+++ b/modules/notifications/Notification.qml
@@ -162,15 +162,11 @@ StyledRect {
width: Math.round(parent.width * 0.6)
height: Math.round(parent.width * 0.6)
- sourceComponent: IconImage {
+ sourceComponent: ColouredIcon {
anchors.fill: parent
source: Quickshell.iconPath(root.modelData.appIcon)
- asynchronous: true
-
+ colour: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
layer.enabled: root.modelData.appIcon.endsWith("symbolic")
- layer.effect: Colouriser {
- colorizationColor: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.modelData.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onTertiaryContainer
- }
}
}