import QtQuick import Quickshell Item { id: root property var entry: null readonly property bool noIcon: entry && entry._noIcon === true readonly property string iconName: entry && entry.icon ? entry.icon : "" readonly property string appName: entry && entry.name ? entry.name : "?" readonly property bool iconOk: !noIcon && iconName.length > 0 && Quickshell.hasThemeIcon(iconName) visible: !noIcon // Hash app name into a stable hue so each fallback tile is distinct but consistent. readonly property int hue: { let h = 0; for (let i = 0; i < appName.length; i++) h = (h * 31 + appName.charCodeAt(i)) | 0; return Math.abs(h) % 360; } Image { id: img anchors.fill: parent source: root.iconOk ? Quickshell.iconPath(root.iconName) : "" fillMode: Image.PreserveAspectFit smooth: true asynchronous: true visible: root.iconOk sourceSize.width: width * 2 sourceSize.height: height * 2 } Rectangle { anchors.fill: parent visible: !root.iconOk radius: width * 0.22 color: Qt.hsla(root.hue / 360, 0.45, 0.35, 1) Text { anchors.centerIn: parent text: root.appName.length > 0 ? root.appName.charAt(0).toUpperCase() : "?" color: "#ffffff" font.family: Theme.fontFamily font.pixelSize: parent.width * 0.55 font.bold: true } } }