import Quickshell import Quickshell.Wayland import Quickshell.Io import Quickshell.Hyprland import QtQuick import QtQuick.Layouts import Quickshell.Services.SystemTray import Quickshell.DBusMenu import Quickshell.Widgets Scope { id: root property string time property int cpuUsage: 0 property string memUsage: "0" property var lastCpuIdle: 0 property var lastCpuTotal: 0 SystemClock { id: sysClock precision: SystemClock.Seconds } Process { id: cpuProc command: ["sh", "-c", "head -1 /proc/stat"] stdout: SplitParser { onRead: data => { if (!data) return; var p = data.trim().split(/\s+/); var idle = parseInt(p[4]) + parseInt(p[5]); var total = p.slice(1, 8).reduce((a, b) => a + parseInt(b), 0); if (lastCpuTotal > 0) { cpuUsage = Math.round(100 * (1 - (idle - lastCpuIdle) / (total - lastCpuTotal))); } lastCpuTotal = total; lastCpuIdle = idle; } } Component.onCompleted: running = true } // Read raw millidegrees value from sysfs (adjust hwmon index if needed) // command: ["cat", "/sys/class/hwmon/hwmon0/temp1_input"] Process { id: memProc command: ["sh", "-c", "free -m | grep Mem"] stdout: SplitParser { onRead: data => { if (!data) return; var parts = data.trim().split(/\s+/); var total = (parts[1] / 1000).toFixed(2) || 1; var used = (parts[2] / 1000).toFixed(2) || 0; memUsage = `${used} / ${total}`; } } Component.onCompleted: running = true } Timer { interval: 1000 running: true repeat: true onTriggered: { cpuProc.running = true; memProc.running = true; } } Variants { model: Quickshell.screens PanelWindow { id: barRoot required property var modelData screen: modelData readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen) // Theme property color colBg: Qt.rgba(0.0, 0.0, 0.0, 0.35)// "#150d16" property color colFg: "#f5dbc4" property color colMuted: "#444b6a" property color colCyan: "#0db9d7" property color colBlue: "#7aa2f7" property color colYellow: "#e0af68" property color colWhite: "#FFFFFF" property color colRed: "#FF2400" property string fontFamily: "Inter" property int fontSize: 16 anchors.bottom: true anchors.left: true anchors.right: true implicitHeight: 35 color: Qt.rgba(0.0, 0.0, 0.0, 0.35) RowLayout { anchors.fill: parent anchors.margins: 8 spacing: 8 // Workspaces Repeater { model: Hyprland.workspaces delegate: Loader { active: modelData.monitor && modelData.monitor.name === monitor.name && modelData.id != -98 sourceComponent: Text { property bool isActive: Hyprland.focusedWorkspace?.id === modelData.id text: modelData.id color: isActive ? barRoot.colRed : barRoot.colFg font { family: barRoot.fontFamily pixelSize: barRoot.fontSize bold: true } MouseArea { anchors.fill: parent onClicked: ws.activate() } } } } Row { spacing: 4 Repeater { model: barRoot.monitor?.activeWorkspace?.toplevels ?? null delegate: Item { id: appIconRoot width: 18 height: 18 property var desktopEntry: DesktopEntries.byId(modelData.wayland.appId) IconImage { anchors.fill: parent source: Quickshell.iconPath(desktopEntry.icon ?? modelData.appId, "image-missing") opacity: modelData.activated ? 1.0 : 0.35 } MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton onClicked: mouse => { if (mouse.button === Qt.LeftButton) { modelData.wayland.activate(); } else if (mouse.button === Qt.RightButton) { modelData.wayland.close(); } } } } } Connections { target: barRoot.monitor?.activeWorkspace?.toplevels ?? null function onObjectInsertedPost() { Hyprland.refreshToplevels(); } function onObjectRemovedPost() { Hyprland.refreshToplevels(); } } } Text { id: clock anchors.centerIn: parent property var timeFmt: "h:mm:ss AP" property var timeStr: Qt.formatDateTime(sysClock.date, timeFmt) color: barRoot.colFg font { family: barRoot.fontFamily pixelSize: barRoot.fontSize bold: true } text: timeStr Calendar { visible: clockArea.containsMouse anchorItem: clock today: sysClock.date bgColor: barRoot.colBg fgColor: barRoot.colFg mutedColor: barRoot.colMuted accentColor: barRoot.colRed fontFamily: barRoot.fontFamily fontSize: barRoot.fontSize } MouseArea { id: clockArea hoverEnabled: true anchors.fill: parent onClicked: { clock.timeFmt = (clock.timeFmt === "h:mm:ss AP") ? "dddd M/d/yyyy - h:mm:ss AP" : "h:mm:ss AP"; } } } Item { Layout.fillWidth: true } IconImage { implicitSize: 20 source: Quickshell.iconPath("device_cpu") } // CPU Text { text: `${cpuUsage}%` color: barRoot.colFg font { family: barRoot.fontFamily pixelSize: barRoot.fontSize bold: true } } Rectangle { width: 1 height: 16 color: barRoot.colMuted } IconImage { implicitSize: 20 source: Quickshell.iconPath("memory") } // Memory Text { text: `${memUsage} GB` color: barRoot.colFg font { family: barRoot.fontFamily pixelSize: barRoot.fontSize bold: true } } Row { spacing: 5 Repeater { model: SystemTray.items delegate: Image { id: trayIcon source: modelData.icon width: 16 height: 16 QsMenuOpener { id: menuOpener menu: modelData.menu } PopupWindow { id: tooltip visible: trayDelegate.containsMouse color: "transparent" implicitWidth: tooltipText.implicitWidth + 16 implicitHeight: tooltipText.implicitHeight + 10 anchor.item: trayIcon anchor.edges: Edges.Top | Edges.Left anchor.gravity: Edges.Top | Edges.Right anchor.adjustment: PopupAdjustment.SlideX | PopupAdjustment.FlipY anchor.margins.bottom: 6 Rectangle { anchors.fill: parent color: barRoot.colBg radius: 4 border.color: barRoot.colMuted border.width: 1 Text { id: tooltipText anchors.centerIn: parent text: modelData.tooltipTitle || modelData.id color: barRoot.colFg font { family: barRoot.fontFamily pixelSize: barRoot.fontSize - 2 } } } } MouseArea { id: trayDelegate hoverEnabled: true anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton onClicked: mouse => { if (mouse.button === Qt.LeftButton) { modelData.activate(); } else if (mouse.button === Qt.RightButton && modelData.hasMenu) { let pos = trayIcon.mapToItem(null, 0, trayIcon.height); modelData.display(barRoot, pos.x, pos.y); } } } } } } } BackgroundEffect.blurRegion: Region { item: barRoot.contentItem } } } }