A chamfer with no neighbour behind it now carries the corner it removed, put back OUTSIDE the panel as a detached accent triangle. capGap is the perpendicular distance from the cut, hence the per-axis shift of capGap over root 2: the cap moves along the cut's normal, not along an axis. The trace joining two caps belongs to the RAIL, not the panel — the run it draws is the gap BETWEEN two panels, which no panel can see. HyprChromeBar filters the row down to panels (a slack Item has no `rightChamfer`, so spacers drop out, and dropping them is exactly what makes a trace span them), then joins each right cap to the next left cap: straight, one 45° step at the midpoint of the gap, straight. It meets the middle of each cap's outward face rather than its tip. TestPanel is a staging slot between two spacers. It counts seconds since load, which is the cheapest proof the panel is live, and standing alone it exercises a cap and a trace at both ends — something a rail of butted panels never does. Restructures the module in the same commit, since the moves and the edits above land in the same files: folders are PascalCase, the bar and its widgets moved under Widgets/Bar, and DebugWindow takes the HyprChrome Theme instead of the legacy one. The two singletons are identical today, so that is not a visual fix — it is a palette edit reaching the debug stage in future. Rename detection needs -M40% to follow HyprChromeBar, which grew past the default similarity threshold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U19X5LGTxtq4pb4jdNVivv
81 lines
2.0 KiB
QML
81 lines
2.0 KiB
QML
pragma ComponentBehavior: Bound
|
|
|
|
import Quickshell
|
|
import Quickshell.Services.SystemTray
|
|
import QtQuick
|
|
import qs.HyprChrome.Theme
|
|
import qs.HyprChrome.Widgets.Bar.Panels
|
|
|
|
// System tray in the hyprchrome panel chrome, in both densities: the same
|
|
// items, drawn large enough to hit when expanded and shrunk onto the header
|
|
// line when collapsed.
|
|
//
|
|
// Unlike the other panels this one sizes itself horizontally — the item count
|
|
// is whatever the session happens to be running — so a layout can just give it
|
|
// `Layout.fillHeight` and let its implicit width stand.
|
|
BarPanel {
|
|
id: panel
|
|
|
|
panelId: "TRY"
|
|
title: "SYSTEM TRAY"
|
|
meta: panel.itemCount + (panel.itemCount === 1 ? " ITEM" : " ITEMS")
|
|
|
|
readonly property int itemCount: SystemTray.items.values.length
|
|
|
|
implicitWidth: Math.max(panel.headerMinWidth,
|
|
panel.briefLeft + brief.implicitWidth + panel.padding,
|
|
panel.padding * 2 + icons.implicitWidth)
|
|
|
|
// Collapsed: the same icons, small, on the header line.
|
|
summary: Row {
|
|
id: brief
|
|
|
|
spacing: 5
|
|
|
|
Repeater {
|
|
model: SystemTray.items
|
|
|
|
TrayIcon {
|
|
iconSize: 13
|
|
}
|
|
}
|
|
|
|
Text {
|
|
visible: panel.itemCount === 0
|
|
text: "NO ITEMS"
|
|
color: Theme.muted
|
|
font.family: Theme.microFont
|
|
font.pixelSize: 9
|
|
font.letterSpacing: 1.2
|
|
height: 21
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
|
|
// Expanded: full-size cells.
|
|
Row {
|
|
id: icons
|
|
|
|
spacing: 8
|
|
|
|
Repeater {
|
|
model: SystemTray.items
|
|
|
|
TrayIcon {
|
|
iconSize: 18
|
|
}
|
|
}
|
|
|
|
Text {
|
|
visible: panel.itemCount === 0
|
|
text: "NO ITEMS"
|
|
color: Theme.muted
|
|
font.family: Theme.microFont
|
|
font.pixelSize: 9
|
|
font.letterSpacing: 1.2
|
|
height: 26
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
}
|