The last of Section F, and the only thing in Panama that reads an authentication token, so most of the design is about that rather than about the number. It never refreshes the token and never writes to the credentials file. That token expires roughly hourly and Claude Code refreshes it on demand; if this refreshed it too, two processes would be rotating one credential, and a rotation invalidates the other holder's copy. The failure mode is being silently signed out of Claude Code by a status widget, which no bar indicator is worth. So it reads the token, uses it while valid, and reports "waiting for Claude Code to refresh" when not -- which covers the case that matters, because while you are using Claude Code the token is fresh, and while you are not there is nothing to watch. The token never reaches argv either: curl takes the Authorization header on stdin through --config, because a header passed as an argument sits in /proc/<pid>/cmdline for the length of the request. Same rule the password and MOK paths already follow. And it never reaches the output: the record carries percentages and timestamps and nothing else. Both are pinned, and both were checked by sabotaging the collector to pass -H and watching the contract name it. Off by default. It is a coding-tool readout, not something a general-purpose desktop shows without being asked, and it hides unless the collector has real numbers rather than displaying "unknown".
145 lines
4.5 KiB
QML
145 lines
4.5 KiB
QML
// The top bar: edge-to-edge system chrome with no surface of its own. Content
|
|
// floats directly over the desktop, while individual controls still provide
|
|
// hover and press feedback. The entire bar is a hit target so the top-left
|
|
// corner remains a dependable workspace-scroll gesture.
|
|
//
|
|
// Instantiate one per screen:
|
|
//
|
|
// Variants {
|
|
// model: Quickshell.screens
|
|
// Bar {}
|
|
// }
|
|
//
|
|
// Layout mirrors GNOME's: workspaces + vitals left, clock + weather center,
|
|
// media + tray + status cluster right.
|
|
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import QtQuick
|
|
import qs.config
|
|
import qs.modules.clipboard
|
|
import qs.modules.focus
|
|
|
|
PanelWindow {
|
|
id: root
|
|
|
|
// Set by Variants. Left as a plain property (not `required`) so the bar can
|
|
// also be instantiated standalone on the default screen while testing.
|
|
property var modelData: null
|
|
|
|
// Raised when the status cluster is clicked; the shell wires this to the
|
|
// quick settings panel, which this module does not own.
|
|
signal requestQuickSettings
|
|
|
|
// Bound by the shell when an idle inhibitor is held, so the cluster can
|
|
// show the caffeine glyph.
|
|
property alias idleInhibited: statusCluster.idleInhibited
|
|
|
|
screen: root.modelData
|
|
|
|
anchors {
|
|
top: true
|
|
left: true
|
|
right: true
|
|
}
|
|
|
|
// PanelWindow defaults to an opaque white background.
|
|
color: "transparent"
|
|
|
|
implicitHeight: Theme.barHeight
|
|
|
|
exclusiveZone: Theme.barHeight
|
|
|
|
// Stable namespace for compositor inspection and shell diagnostics.
|
|
WlrLayershell.namespace: "qs-bar"
|
|
WlrLayershell.layer: WlrLayer.Top
|
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
|
|
|
// The full-width region is intentional: unlike a floating island, a menu
|
|
// bar owns the screen edge. In particular, Workspaces starts at x=0 and
|
|
// spans the full height so scrolling at the literal corner always works.
|
|
mask: Region {
|
|
item: barContent
|
|
}
|
|
|
|
Item {
|
|
id: barContent
|
|
|
|
anchors.fill: parent
|
|
|
|
// ── Left ────────────────────────────────────────────────────────────
|
|
Row {
|
|
anchors.left: parent.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Theme.itemSpacing
|
|
|
|
Workspaces {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
screen: root.screen
|
|
}
|
|
|
|
AgentUsageWidget {}
|
|
|
|
VitalsWidget {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
// ── Center ──────────────────────────────────────────────────────────
|
|
Row {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 2
|
|
|
|
Clock {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
WeatherWidget {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
}
|
|
|
|
// ── Right ───────────────────────────────────────────────────────────
|
|
Row {
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: Theme.itemSpacing
|
|
|
|
CalendarIndicator {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
HealthIndicator {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
ActivityIndicator {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
FocusIndicator {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
MediaWidget {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
ClipboardWidget {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
Tray {
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
}
|
|
|
|
StatusCluster {
|
|
id: statusCluster
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
onRequestQuickSettings: root.requestQuickSettings()
|
|
}
|
|
}
|
|
}
|
|
}
|