// 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() } } } }