diff --git a/hypr/hyprland.conf b/hypr/hyprland.conf index 9c56439..713a951 100644 --- a/hypr/hyprland.conf +++ b/hypr/hyprland.conf @@ -41,6 +41,7 @@ $programs = rofi -show drun # exec-once = nm-applet & # exec-once = waybar & hyprpaper & firefox exec-once = /usr/lib/hyprpolkitagent/hyprpolkitagent +exec-once = /usr/bin/qs & ############################# ### ENVIRONMENT VARIABLES ### diff --git a/quickshell/.qmlls.ini b/quickshell/.qmlls.ini new file mode 120000 index 0000000..a47eb94 --- /dev/null +++ b/quickshell/.qmlls.ini @@ -0,0 +1 @@ +/run/user/1000/quickshell/vfs/4ae8f7ef09a48f8dc93b6ec90ac7277a/.qmlls.ini \ No newline at end of file diff --git a/quickshell/shell.qml b/quickshell/shell.qml new file mode 100644 index 0000000..a0dae13 --- /dev/null +++ b/quickshell/shell.qml @@ -0,0 +1,224 @@ +import Quickshell +import Quickshell.Wayland +import Quickshell.Hyprland +import Quickshell.Io +import QtQuick +import QtQuick.Layouts + +PanelWindow { + id: root + + // ===================== + // System stats + // ===================== + property int cpuUsage: 0 + property int memUsage: 0 + + property var lastCpuIdle: 0 + property var lastCpuTotal: 0 + + Process { + id: cpuProc + command: ["cat", "/proc/stat"] + stdout: { + console.log(stdout); + console.log("test"); + var line = stdout.split("\n")[0].split(/\s+/); + + var user = parseInt(line[1]); + var nice = parseInt(line[2]); + var system = parseInt(line[3]); + var idle = parseInt(line[4]); + var iowait = parseInt(line[5]); + var irq = parseInt(line[6]); + var softirq = parseInt(line[7]); + + var idleAll = idle + iowait; + var total = user + nice + system + idle + iowait + irq + softirq; + + var diffIdle = idleAll - lastCpuIdle; + var diffTotal = total - lastCpuTotal; + + if (diffTotal > 0) { + cpuUsage = Math.round(100 * (1 - diffIdle / diffTotal)); + } + + console.log("diffTotal is " + diffTotal); + + lastCpuIdle = idleAll; + lastCpuTotal = total; + } + } + + 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 + } + + // Update loop + Timer { + interval: 2000 + running: true + repeat: true + onTriggered: { + cpuProc.running = true; + memProc.running = true; + } + } + + // ===================== + // Theme + // ===================== + property color colBg: "#1a1b26" + property color colMuted: "#444b6a" + property color colCyan: "#0db9d7" + property color colBlue: "#7aa2f7" + property color colMagenta: "#e528c2" + property color colYellow: "#e0af68" + + property string fontFamily: "JetBrainsMono Nerd Font" + property int fontSize: 14 + + // ===================== + // Helpers + // ===================== + function getWorkspace(id) { + var list = Hyprland.workspaces.values; + for (var i = 0; i < list.length; i++) { + if (list[i].id === id) + return list[i]; + } + return null; + } + + function isWorkspaceActive(id) { + return Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.id === id; + } + + // ===================== + // Layout + // ===================== + anchors.top: true + anchors.left: true + anchors.right: true + implicitHeight: 30 + color: root.colBg + + RowLayout { + anchors.fill: parent + anchors.margins: 8 + + // ===================== + // LEFT: Workspaces + // ===================== + RowLayout { + spacing: 6 + + Repeater { + model: 9 + + Text { + required property int index + + property int wsId: index + 1 + property var ws: root.getWorkspace(wsId) + + text: wsId + + color: root.isWorkspaceActive(wsId) ? root.colCyan : (ws ? root.colMagenta : root.colMuted) + + font { + family: root.fontFamily + pixelSize: root.fontSize + bold: true + } + + MouseArea { + anchors.fill: parent + onClicked: Hyprland.dispatch("workspace " + wsId) + } + } + } + } + + // Spacer + Item { + Layout.fillWidth: true + } + + // ===================== + // RIGHT: System info + // ===================== + RowLayout { + spacing: 10 + + // CPU (placeholder, hook later) + Text { + id: cpuText + text: "CPU: " + cpuUsage + "%" + color: root.colYellow + font.pixelSize: root.fontSize + font.family: root.fontFamily + font.bold: true + } + + Rectangle { + width: 1 + height: 16 + color: root.colMuted + } + + // Memory (placeholder) + Text { + id: memText + text: "Mem: " + memUsage + "%" + color: root.colCyan + font.pixelSize: root.fontSize + font.family: root.fontFamily + font.bold: true + } + + Rectangle { + width: 1 + height: 16 + color: root.colMuted + } + + // Clock + Text { + id: clock + color: root.colBlue + + font { + family: root.fontFamily + pixelSize: root.fontSize + bold: true + } + + function updateTime() { + text = Qt.formatDateTime(new Date(), "ddd, MMM dd - HH:mm"); + } + + Component.onCompleted: updateTime() + + Timer { + interval: 1000 + running: true + repeat: true + onTriggered: clock.updateTime() + } + } + } + } +}