pragma ComponentBehavior: Bound import Quickshell import QtQuick import QtQuick.Layouts import qs.Modules import qs.Config import qs.Modules.SysTray import qs.Modules.Network import qs.Modules.Updates GridLayout { id: root required property bool fullscreen required property bool horizontal required property Wrapper popouts required property ClipWrapper popoutsWrapper required property ShellScreen screen readonly property int vPadding: 6 required property PersistentProperties visibilities function axisCenterOf(item: Item): real { const c = item.mapToItem(root, item.implicitWidth / 2, item.implicitHeight / 2); return horizontal ? c.x : c.y; } function checkPopout(pos: real): void { const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper; const id = ch?.entryId; if (!ch || id === undefined) { if (!popouts.currentName.startsWith("traymenu") || Config.bar.tray.showOnHover) popouts.hasCurrent = false; return; } if (visibilities.sidebar || visibilities.dashboard || visibilities.resources || visibilities.settings) return; if (id === "statusIcons" && Config.bar.popouts.statusIcons) { const items = (ch.item as StatusIcons).items; const icon = horizontal ? items.childAt(mapToItem(items, pos, 0).x, items.height / 2) : items.childAt(items.width / 2, mapToItem(items, 0, pos).y); if (icon) { popouts.currentName = icon.name; popouts.currentCenter = Qt.binding(() => axisCenterOf(icon)); popouts.hasCurrent = true; } } else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) { const tray = ch.item as TrayIcons; const layout = tray.layout; const trayItem = horizontal ? layout.childAt(mapToItem(layout, pos, 0).x, layout.height / 2) : layout.childAt(tray.width / 2, mapToItem(layout, 0, pos).y); if (trayItem) { const idx = trayItem.index; popouts.currentName = `traymenu${idx}`; popouts.currentCenter = Qt.binding(() => axisCenterOf(trayItem)); popouts.hasCurrent = true; } if (!popouts.currentName.startsWith("traymenu")) popouts.hasCurrent = false; } if (id === "updates") { popouts.currentName = "updates"; popouts.currentCenter = Qt.binding(() => axisCenterOf(ch.item as Item)); popouts.hasCurrent = true; } } function entryAt(pos: real): string { const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper; return ch?.entryId ?? ""; } columnSpacing: Appearance.spacing.small columns: horizontal ? -1 : 1 rowSpacing: Appearance.spacing.small Repeater { id: repeater model: ScriptModel { values: Config.bar.entries.filter(e => e.enabled) } DelegateChooser { role: "id" DelegateChoice { roleValue: "hyprsunset" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal HyprsunsetWidget { horizontal: root.horizontal visible: !root.fullscreen } } } DelegateChoice { roleValue: "spacer" delegate: EntryWrapper { Layout.fillHeight: !root.horizontal Layout.fillWidth: root.horizontal } } DelegateChoice { roleValue: "workspaces" delegate: EntryWrapper { Workspaces { horizontal: root.horizontal screen: root.screen visible: !root.fullscreen } } } DelegateChoice { roleValue: "tray" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal TrayIcons { horizontal: root.horizontal loader: root popouts: root.popouts visible: !root.fullscreen } } } DelegateChoice { roleValue: "statusIcons" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal StatusIcons { horizontal: root.horizontal } } } DelegateChoice { roleValue: "resources" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal Resources { horizontal: root.horizontal visibilities: root.visibilities visible: !root.fullscreen } } } DelegateChoice { roleValue: "updates" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal UpdatesWidget { horizontal: root.horizontal visible: !root.fullscreen } } } DelegateChoice { roleValue: "notifBell" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal NotifBell { horizontal: root.horizontal popouts: root.popouts visibilities: root.visibilities visible: !root.fullscreen } } } DelegateChoice { roleValue: "clock" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal Clock { horizontal: root.horizontal loader: root popouts: root.popouts visibilities: root.visibilities visible: !root.fullscreen } } } DelegateChoice { roleValue: "activeWindow" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal WindowTitle { bar: root horizontal: root.horizontal visible: !root.fullscreen } } } DelegateChoice { roleValue: "network" delegate: EntryWrapper { NetworkWidget { } } } DelegateChoice { roleValue: "media" delegate: EntryWrapper { Layout.fillWidth: !root.horizontal MediaWidget { horizontal: root.horizontal visible: !root.fullscreen } } } } } component EntryWrapper: Item { readonly property string entryId: modelData.id required property int index default property Item item required property var modelData Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter Layout.bottomMargin: !root.horizontal && index === repeater.count - 1 ? root.vPadding : 0 Layout.leftMargin: root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && root.horizontal) ? -root.rowSpacing + Appearance.spacing.extraSmall : root.horizontal ? 0 : Appearance.padding.smaller Layout.rightMargin: root.horizontal && index === repeater.count - 1 ? root.vPadding : root.horizontal ? 0 : Appearance.padding.smaller Layout.topMargin: !root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && !root.horizontal) ? -root.columnSpacing + Appearance.spacing.extraSmall : 0 children: item implicitHeight: item?.implicitHeight ?? 0 implicitWidth: item?.implicitWidth ?? 0 } }