From 379404a90c818654a669ef0ec6ef2ed208c69079 Mon Sep 17 00:00:00 2001 From: Rosty Hnatyshyn Date: Wed, 5 Aug 2026 21:47:45 -0700 Subject: [PATCH] add quickshell --- quickshell/Bar.qml | 181 +++++++++++++++++++++++++++++++++++++++++++ quickshell/shell.qml | 5 ++ 2 files changed, 186 insertions(+) create mode 100644 quickshell/Bar.qml create mode 100644 quickshell/shell.qml diff --git a/quickshell/Bar.qml b/quickshell/Bar.qml new file mode 100644 index 0000000..03b20ac --- /dev/null +++ b/quickshell/Bar.qml @@ -0,0 +1,181 @@ +import Quickshell +import Quickshell.Wayland +import Quickshell.Io +import Quickshell.Hyprland +import QtQuick +import QtQuick.Layouts + +import Quickshell.Services.SystemTray +import Quickshell.DBusMenu +Scope { + id: root + property string time + + property int cpuUsage: 0 + property int 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 | grep Mem"] + stdout: SplitParser { + onRead: data => { + if (!data) return + var parts = data.trim().split(/\s+/) + var total = parseInt(parts[1]) || 1 + var used = parseInt(parts[2]) || 0 + memUsage = Math.round(100 * 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 { + required property var modelData + screen: modelData + readonly property HyprlandMonitor monitor: Hyprland.monitorFor(screen) + + id: barRoot + + // Theme + property color colBg: "#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: root.fontFamily; pixelSize: root.fontSize; bold: true } + + MouseArea { + anchors.fill: parent + onClicked: ws.activate() + } + } + } + } + + 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: root.fontFamily; pixelSize: root.fontSize; bold: true } + text: timeStr + + MouseArea { + anchors.fill: parent + onClicked: { clock.timeFmt = (clock.timeFmt === "h:mm:ss AP") ? "ddd, MMM d - h:mm:ss AP" : "h:mm:ss AP" } + } + } + + Item { Layout.fillWidth: true } + + // CPU + Text { + text: "CPU: " + cpuUsage + "%" + color: barRoot.colFg + font { family: root.fontFamily; pixelSize: root.fontSize; bold: true } + } + + Rectangle { width: 1; height: 16; color: root.colMuted } + + // Memory + Text { + text: "Mem: " + memUsage + "%" + color: barRoot.colFg + font { family: root.fontFamily; pixelSize: root.fontSize; bold: true } + } + + + Row { + spacing: 5 + Repeater { + model: SystemTray.items + delegate: Image { + source: modelData.icon + width: 16 + height: 16 + + MouseArea { + anchors.fill: parent + onClicked: modelData.activate() + } + } + } + } + + } + } + } +} diff --git a/quickshell/shell.qml b/quickshell/shell.qml new file mode 100644 index 0000000..9d093ad --- /dev/null +++ b/quickshell/shell.qml @@ -0,0 +1,5 @@ +import Quickshell + +Scope { + Bar {} +}