import Quickshell import Quickshell.Services.SystemTray import Quickshell.Widgets import QtQuick import "../components" Item { id: root required property var barWindow implicitWidth: trayRow.width implicitHeight: 24 Row { id: trayRow anchors.verticalCenter: parent.verticalCenter spacing: 3 Repeater { model: SystemTray.items delegate: Item { id: trayDelegate required property var modelData width: 24 height: 24 // Hover highlight Rectangle { anchors.fill: parent radius: Theme.radius color: hoverArea.containsMouse ? Qt.rgba(1,1,1,0.08) : "transparent" Behavior on color { ColorAnimation { duration: 80 } } } IconImage { id: iconImg anchors.centerIn: parent implicitSize: 16 visible: status === Image.Ready source: { const icon = trayDelegate.modelData.icon if (!icon || icon === "") return "" if (icon.startsWith("/") || icon.startsWith("file://") || icon.startsWith("image://")) return icon const path = Quickshell.iconPath(icon, "") if (path !== "") return "file://" + path return "image://icon/" + icon } mipmap: true } // Letter fallback when icon fails to load Text { anchors.centerIn: parent visible: iconImg.status !== Image.Ready text: (trayDelegate.modelData.title ?? trayDelegate.modelData.id ?? "?").charAt(0).toUpperCase() color: Theme.textDim font.pixelSize: 11 font.bold: true } MouseArea { id: hoverArea anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: mouse => { const item = trayDelegate.modelData const wantsMenu = mouse.button === Qt.RightButton || item.onlyMenu if (wantsMenu && item.hasMenu) { // display() needs the quickshell PanelWindow (not QQuickWindow). // mapToItem(null) gives scene/window-local coordinates. const pos = trayDelegate.mapToItem(null, 0, trayDelegate.height) item.display(root.barWindow, Math.round(pos.x), Math.round(pos.y)) } else if (!item.onlyMenu) { item.activate() } } } } } } }