pragma Singleton import QtQuick import Quickshell import Quickshell.Io Item { id: root // Per-workspace icon cache: maps workspaceId -> array of icon strings property var workspaceIcons: ({}) function iconsForWorkspace(workspaceId) { return root.workspaceIcons[workspaceId] || [] } function matchIcon(name) { if (!name) return "" var lower = name.toLowerCase() if (iconMap[lower]) return iconMap[lower] for (var key in iconMap) { if (key.endsWith("*") && key.startsWith("*")) { var middle = key.slice(1, -1) if (lower.indexOf(middle) !== -1) return iconMap[key] } else if (key.endsWith("*")) { var prefix = key.slice(0, -1) if (lower.startsWith(prefix)) return iconMap[key] } else if (key.startsWith("*")) { var suffix = key.slice(1) if (lower.endsWith(suffix)) return iconMap[key] } } return "" } Process { id: clientsProc command: ["hyprctl", "clients", "-j"] running: true stdout: StdioCollector { onStreamFinished: { try { var data = JSON.parse(this.text.trim()) var newIcons = {} for (var i = 0; i < data.length; i++) { var client = data[i] var wid = client.workspace.id var icon = root.matchIcon(client.initialTitle) || root.matchIcon(client.initialClass) || "\"" + client.initialTitle + "\"" if (icon) { if (!newIcons[wid]) newIcons[wid] = [] newIcons[wid].push(icon) } } root.workspaceIcons = newIcons } catch (e) { // hyprctl output was not valid JSON } } } } Timer { interval: 1000 running: true repeat: true triggeredOnStart: true onTriggered: clientsProc.running = true } readonly property var iconMap: ({ // Youtube "grayjay": "", // Browser "ablaze floorp": "", "floorp": "", "librewolf": "", "midori": "", "brave-browser": "", "chromium": "", // E-Mail "*thunderbird": "󰇮", // Terminals "kitty": "", "alacritty": "", // Videoplayer "vlc media player": "󰕼", "mpv": "", "ffplay": "", // Video editing "org.kde.kdenlive": "", // Video "*obs*": "󰨜", "hyprland-share-picker": "󱎴", // Chats "discord": "", "vesktop": "", "signal": "󰭹", "xyz.chatboxapp.app": "", // Coding "visual studio code": "", "vscodium": "", "jetbrains-idea": "", "jetbrains-studio": "", // Text Editor "org.xfce.mousepad": "󱩼", // Password "org.keepassxc.keepassxc": "", "yubico authenticator": "", // Cloud "com.nextcloud*": "󰅟", // App Store "octopi": "󰒚", // Games "steam*": "", "org.prismlauncher*": "󰍳", "minecraft*": "󰍳", "game": "", "eden*": "", // Digital Arts "blender": "", // Image Editor "gimp": "󱇣", "*inkscape*": "󱇣", "krita": "", // VM "virt*": "", "remote-viewer": "", // Audio "*qpwgraph": "󱡫", "carla": "󱡫", "volume*": "", "pavucontrol": "", // Document Editor/Viewer "libreoffice-startcenter": "", "libreoffice-base": "", "libreoffice-calc": "󱎏", "libreoffice-draw": "󱎐", "libreoffice-impress": "", "libreoffice-math": "", "libreoffice-writer": "󱎒", "*rnote": "󱩼", "xreader": "󱩼", "*xournalpp*": "󱩼", "qpdfview*": "󱩼", // Hardware "mission center": "", "qdirstat": "󰋊", "disks": "󰋊", // File Manager "nemo": "󰉋", "org.gnome.nautilus": "󰉋", "org.kde.dolphin": "󰉋", "xdg-desktop-portal-gtk": "󰉋", // Settings "nwg-look": "", "qt5ct": "", "qt6ct": "", "sddm-conf": "", "org.gnome.Settings": "", "blueman*": "󰂯", "nm-connection-editor": "󱛆", "nm-applet": "󱛆", // Calculator "calculator": "󰪚", // VPN "*vpn": "󰳌", "*cisco*": "󰳌", // Torrent "*qbittorrent*": "󰉍", // Hardware Design "xilinx*": "", "vsim": "", "*ivado*": "", // BoxBuddy "*boxbuddy*": "󰒋", // Stream "fladder": "󰼁", "crunchyroll": "", "netflix": "", "primevideo": "󰯜", // Image Viewer "viewnior": "", // CNC "lightburn": "󱇣", "wofi": "", // Screenshare "moonlight": "󰍹ßß" }) }