fix: don't cache icons + fix bg colour when transparent image

Also don't double cache
This commit is contained in:
2 * r + 2 * t 2026-04-20 00:52:32 +10:00
parent b004edad7d
commit 89cb3b9d7c
3 changed files with 22 additions and 39 deletions

View file

@ -4,7 +4,6 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Shapes import QtQuick.Shapes
import Quickshell import Quickshell
import Quickshell.Widgets
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
import Caelestia.Config import Caelestia.Config
import qs.components import qs.components
@ -117,8 +116,9 @@ StyledRect {
height: TokenConfig.sizes.notifs.image height: TokenConfig.sizes.notifs.image
visible: root.hasImage || root.hasAppIcon visible: root.hasImage || root.hasAppIcon
sourceComponent: ClippingRectangle { sourceComponent: StyledClippingRect {
radius: Tokens.rounding.full radius: Tokens.rounding.full
color: root.modelData.urgency === NotificationUrgency.Critical ? Colours.palette.m3error : root.modelData.urgency === NotificationUrgency.Low ? Colours.layer(Colours.palette.m3surfaceContainerHighest, 2) : Colours.palette.m3secondaryContainer
implicitWidth: TokenConfig.sizes.notifs.image implicitWidth: TokenConfig.sizes.notifs.image
implicitHeight: TokenConfig.sizes.notifs.image implicitHeight: TokenConfig.sizes.notifs.image

View file

@ -19,36 +19,17 @@ StyledRect {
required property DrawerVisibilities visibilities required property DrawerVisibilities visibilities
readonly property list<var> notifs: Notifs.list.filter(n => n.appName === modelData) readonly property list<var> notifs: Notifs.list.filter(n => n.appName === modelData)
readonly property var groupProps: { readonly property list<var> activeNotifs: notifs.filter(n => !n.closed)
let count = 0; readonly property int notifCount: activeNotifs.length
let img = ""; readonly property string image: activeNotifs.find(n => n.image.length > 0)?.image ?? ""
let icon = ""; readonly property string appIcon: activeNotifs.find(n => n.appIcon.length > 0)?.appIcon ?? ""
let hasCritical = false; readonly property int urgency: {
let hasNormal = false; if (activeNotifs.find(n => n.urgency === NotificationUrgency.Critical))
for (const n of notifs) { return NotificationUrgency.Critical;
if (!n.closed) { if (activeNotifs.find(n => n.urgency === NotificationUrgency.Normal))
count++; return NotificationUrgency.Normal;
if (!img && n.image.length > 0) return NotificationUrgency.Low;
img = n.image;
if (!icon && n.appIcon.length > 0)
icon = n.appIcon;
if (n.urgency === NotificationUrgency.Critical)
hasCritical = true;
else if (n.urgency === NotificationUrgency.Normal)
hasNormal = true;
}
}
return {
count,
img,
icon,
urgency: hasCritical ? NotificationUrgency.Critical : hasNormal ? NotificationUrgency.Normal : NotificationUrgency.Low
};
} }
readonly property int notifCount: groupProps.count
readonly property string image: groupProps.img
readonly property string appIcon: groupProps.icon
readonly property int urgency: groupProps.urgency
readonly property int nonAnimHeight: { readonly property int nonAnimHeight: {
const headerHeight = header.implicitHeight + (root.expanded ? Math.round(Tokens.spacing.small / 2) : 0); const headerHeight = header.implicitHeight + (root.expanded ? Math.round(Tokens.spacing.small / 2) : 0);
@ -130,7 +111,7 @@ StyledRect {
id: materialIconComp id: materialIconComp
MaterialIcon { MaterialIcon {
text: Icons.getNotifIcon(root.notifs[0]?.summary, root.urgency) text: Icons.getNotifIcon(root.activeNotifs[0]?.summary, root.urgency)
color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer color: root.urgency === NotificationUrgency.Critical ? Colours.palette.m3onError : root.urgency === NotificationUrgency.Low ? Colours.palette.m3onSurface : Colours.palette.m3onSecondaryContainer
font.pointSize: Tokens.font.size.large font.pointSize: Tokens.font.size.large
} }
@ -199,7 +180,7 @@ StyledRect {
StyledText { StyledText {
animate: true animate: true
text: root.notifs.find(n => !n.closed)?.timeStr ?? "" text: root.activeNotifs[0]?.timeStr ?? ""
color: Colours.palette.m3outline color: Colours.palette.m3outline
font.pointSize: Tokens.font.size.small font.pointSize: Tokens.font.size.small
} }

View file

@ -64,7 +64,7 @@ QtObject {
if (status !== Image.Ready || width != TokenConfig.sizes.notifs.image || height != TokenConfig.sizes.notifs.image) if (status !== Image.Ready || width != TokenConfig.sizes.notifs.image || height != TokenConfig.sizes.notifs.image)
return; return;
const cacheKey = notif.appName + notif.summary + notif.id; const cacheKey = notif.appName + notif.summary + notif.id + notif.image;
let h1 = 0xdeadbeef, h2 = 0x41c6ce57, ch; let h1 = 0xdeadbeef, h2 = 0x41c6ce57, ch;
for (let i = 0; i < cacheKey.length; i++) { for (let i = 0; i < cacheKey.length; i++) {
ch = cacheKey.charCodeAt(i); ch = cacheKey.charCodeAt(i);
@ -77,7 +77,6 @@ QtObject {
h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909); h2 ^= Math.imul(h1 ^ (h1 >>> 13), 3266489909);
const hash = (h2 >>> 0).toString(16).padStart(8, 0) + (h1 >>> 0).toString(16).padStart(8, 0); const hash = (h2 >>> 0).toString(16).padStart(8, 0) + (h1 >>> 0).toString(16).padStart(8, 0);
Paths; // Screw you qmlls
const cache = `${Paths.notifimagecache}/${hash}.png`; const cache = `${Paths.notifimagecache}/${hash}.png`;
CUtils.saveItem(this, Qt.resolvedUrl(cache), () => { CUtils.saveItem(this, Qt.resolvedUrl(cache), () => {
notif.image = cache; notif.image = cache;
@ -122,8 +121,7 @@ QtObject {
function onImageChanged(): void { function onImageChanged(): void {
notif.image = notif.notification.image; notif.image = notif.notification.image;
if (notif.notification?.image) notif.maybeTriggerDummyImageLoader();
notif.dummyImageLoader.active = true;
} }
function onExpireTimeoutChanged(): void { function onExpireTimeoutChanged(): void {
@ -183,6 +181,11 @@ QtObject {
} }
} }
function maybeTriggerDummyImageLoader(): void {
if (image && !image.startsWith("image://icon/") && !image.startsWith(Paths.notifimagecache))
dummyImageLoader.active = true;
}
function lock(item: Item): void { function lock(item: Item): void {
locks.add(item); locks.add(item);
} }
@ -212,8 +215,7 @@ QtObject {
appIcon = notification.appIcon; appIcon = notification.appIcon;
appName = notification.appName; appName = notification.appName;
image = notification.image; image = notification.image;
if (notification?.image) maybeTriggerDummyImageLoader();
dummyImageLoader.active = true;
expireTimeout = notification.expireTimeout; expireTimeout = notification.expireTimeout;
hints = notification.hints; hints = notification.hints;
urgency = notification.urgency; urgency = notification.urgency;