Show the current tailnet next to the bar icon
Adds a label to the left of the mark naming the tailnet the selected profile belongs to: the second-from-last label of the domain, so offscale.pastilhas.dev reads "pastilhas" and headscale.pertento.ai reads "pertento". Taking the second-level domain rather than a fixed index keeps the distinctive part if a tailnet ever has four labels. Read from the accounts list the service already polls, so no extra process runs for it. BarIconButton is icon-only by design (labelVisible: false, fixedWidth: slotSize, and its `text` feeds a glyph rather than a label), so the label could not live inside it — the bar widget is now a Row of label + button, and its footprint comes from the row. Coloured with the brand yellow, dimmed by opacity rather than by darkening when Tailscale is off: Qt.darker on yellow shifts the hue to olive instead of quietening it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -329,8 +329,31 @@ Panel {
|
||||
headerIndex = 0
|
||||
}
|
||||
|
||||
implicitWidth: button.implicitWidth
|
||||
implicitHeight: button.implicitHeight
|
||||
implicitWidth: barContent.implicitWidth
|
||||
implicitHeight: barContent.implicitHeight
|
||||
|
||||
// Short name of the tailnet the selected profile belongs to, shown in the bar
|
||||
// beside the icon. Takes the second-from-last label of the domain, which is
|
||||
// the distinctive part:
|
||||
//
|
||||
// headscale.pertento.ai -> pertento
|
||||
// offscale.pastilhas.dev -> pastilhas
|
||||
//
|
||||
// Reads from the accounts list the service already polls, so no extra process
|
||||
// runs for this.
|
||||
readonly property string tailnetName: {
|
||||
var list = tailscale.accounts
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (list[i].selected !== true) continue
|
||||
var parts = String(list[i].tailnet || "").split(".")
|
||||
var clean = []
|
||||
for (var j = 0; j < parts.length; j++) if (parts[j] !== "") clean.push(parts[j])
|
||||
if (clean.length >= 2) return clean[clean.length - 2]
|
||||
if (clean.length === 1) return clean[0]
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
onOpenedChanged: if (opened) {
|
||||
cursorActive = false
|
||||
@@ -372,9 +395,31 @@ Panel {
|
||||
function status(): string { return tailscale.statusText }
|
||||
}
|
||||
|
||||
// Tailnet label to the left of the mark. BarIconButton is icon-only by design
|
||||
// (labelVisible: false, fixedWidth: slotSize, and its `text` feeds a glyph
|
||||
// rather than a label), so the name sits beside it in a Row instead.
|
||||
Row {
|
||||
id: barContent
|
||||
anchors.fill: parent
|
||||
spacing: Style.space(4)
|
||||
|
||||
Text {
|
||||
id: tailnetLabel
|
||||
visible: text !== ""
|
||||
text: root.tailnetName
|
||||
// Brand yellow. Dimmed by opacity rather than by darkening the colour
|
||||
// when Tailscale is off — Qt.darker on yellow slides the hue to olive
|
||||
// instead of just quietening it, the same trap as the IP/DNS subtitle.
|
||||
color: root.accent
|
||||
opacity: tailscale.active ? 1.0 : 0.5
|
||||
font.family: root.fontFamily
|
||||
font.pixelSize: Style.bar.iconFont
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
bar: root.bar
|
||||
// BarIconButton pins its icon Loader to an `opticalCanvas` sized by
|
||||
// Style.bar.iconCanvas (16 * fontScale ~= 27px here). Growing iconSize
|
||||
@@ -403,6 +448,7 @@ Panel {
|
||||
else root.toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardPanel {
|
||||
id: panel
|
||||
|
||||
Reference in New Issue
Block a user