add quickshell bar

This commit is contained in:
Johannes Knopp
2026-04-06 01:30:28 +02:00
parent 8d95eeb892
commit c2b28df404
15 changed files with 1043 additions and 0 deletions

View File

@ -0,0 +1,85 @@
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()
}
}
}
}
}
}
}