import Quickshell import Quickshell.Wayland import Quickshell.Io import Quickshell.Hyprland import QtQuick import QtQuick.Layouts ShellRoot { id: root property color colBg: "#1d2021" // Gruvbox Background (Hard) property color colFg: "#ebdbb2" // Gruvbox Foreground property color colMuted: "#928374" // Gruvbox Gray (Muted) property color colCyan: "#8ec07c" // Gruvbox Aqua/Cyan property color colPurple: "#d3869b" // Gruvbox Purple property color colRed: "#fb4934" // Gruvbox Red (Bright) property color colYellow: "#fabd2f" // Gruvbox Yellow (Bright) property color colBlue: "#83a598" // Gruvbox Blue property color colGreen: "#b8bb26" // Gruvbox Green // Font property string fontFamily: "Iosevka Nerdfont Propo" property int fontSize: 16 // System info properties property string kernelVersion: "Arch" property string powerProfile: "" property int cpuUsage: 0 property string memUsage: "" property string diskUsage: "" property int volumeLevel: 0 property string activeWindow: "Window" property string currentLayout: "Tile" property string cpuTemp: "0" property int cpuTempInt: parseInt(cpuTemp, 10) property string upTime: "0" property color tempColor: { if (cpuTempInt < 50 ) return "#b8bb26" // Gruvbox Green else if (cpuTempInt < 70) return "#fabd2f" // Gruvbox Yellow else return "#fb4934" // Gruvbox Red } property int notificationCount: 0 property var lastCpuIdle: 0 property var lastCpuTotal: 0 property string weatherIcon: " " property string weatherTemp: "--°C" property string weatherPrecip: "--%" property string weatherWind: "--kph" property string netConnection: "" Process { id: connectionProc command: ["sh", "-c", "sed 's/dormant/󰤯 /;s/down/󰤭 /;s/up/󰤨 /' /sys/class/net/wlp8s0/operstate"] stdout: SplitParser { onRead: data => { if (data) netConnection = data.trim() } } Component.onCompleted: running = true } // System UpTime Process { id: upTimeProc command: ["sh", "-c", "uptime|awk '{gsub(\",\",\"\");print $3}'"] // command: ["sh", "-c", "uptime"] stdout: SplitParser { onRead: data => { if (data) upTime = data.trim() } } Component.onCompleted: running = true } // CPU usage Process { id: cpuProc command: ["sh", "-c", "head -1 /proc/stat"] stdout: SplitParser { onRead: data => { if (!data) return var parts = data.trim().split(/\s+/) var user = parseInt(parts[1]) || 0 var nice = parseInt(parts[2]) || 0 var system = parseInt(parts[3]) || 0 var idle = parseInt(parts[4]) || 0 var iowait = parseInt(parts[5]) || 0 var irq = parseInt(parts[6]) || 0 var softirq = parseInt(parts[7]) || 0 var total = user + nice + system + idle + iowait + irq + softirq var idleTime = idle + iowait if (lastCpuTotal > 0) { var totalDiff = total - lastCpuTotal var idleDiff = idleTime - lastCpuIdle if (totalDiff > 0) cpuUsage = Math.round(100 * (totalDiff - idleDiff) / totalDiff) } lastCpuTotal = total lastCpuIdle = idleTime } } Component.onCompleted: running = true } // Notification monitor Process { id: notifListener command: ["sh", "-c", "dbus-monitor \"interface='org.freedesktop.Notifications',member='Notify'\" \"interface='org.freedesktop.Notifications',member='NotificationClosed'\""] running: true stdout: SplitParser { onRead: data => { countPoller.running = true } } } // Notification Updater Process { id: countPoller command: ["sh", "-c", "dunstctl count | awk -F : '/History/ {print $2}'"] stdout: SplitParser { onRead: data => { if (data) notificationCount = parseInt(data.trim()) } } } // show notification history Process { id: showHistoryProc command: ["sh", "-c", "count=$(dunstctl count history); for i in $(seq 1 $count); do dunstctl history-pop; done"] } // clear notifications Process { id: clearAllProc command: ["dunstctl", "history-clear"] onExited: { countPoller.running = true; } } // Memory usage Process { id: memProc command: ["sh", "-c", "free -h | grep Mem"] stdout: SplitParser { onRead: data => { if (!data) return var parts = data.trim().split(/\s+/) var used = parts[2] || "0" memUsage = used } } Component.onCompleted: running = true } // Weather Process { id: weatherProc // Call your python script directly command: ["python3", "/opt/scripts/weather.py"] stdout: SplitParser { onRead: data => { if (!data || data.trim() === "") return var parts = data.trim().split(/\s+/) if (parts.length >= 4) { weatherIcon = parts[0] weatherTemp = parts[1] weatherPrecip = parts[2] + " " + parts[3] weatherWind = parts[4] + " " + parts[5] } } } Component.onCompleted: running = true } // Disk usage Process { id: diskProc command: ["sh", "-c", "df -h / | tail -1"] stdout: SplitParser { onRead: data => { if (!data) return var parts = data.trim().split(/\s+/) var StrInGB = parts[2] || "0G" diskUsage = StrInGB } } Component.onCompleted: running = true } // Volume level Process { id: volProc command: ["wpctl", "get-volume", "@DEFAULT_AUDIO_SINK@"] stdout: SplitParser { onRead: data => { if (!data) return var match = data.match(/Volume:\s*([\d.]+)/) if (match) volumeLevel = Math.round(parseFloat(match[1]) * 100) } } Component.onCompleted: running = true } // Active window title Process { id: windowProc command: ["sh", "-c", "hyprctl activewindow -j | jq -r '.title // empty'"] stdout: SplitParser { onRead: data => { if (data && data.trim()) activeWindow = data.trim() } } Component.onCompleted: running = true } // Current layout Process { id: layoutProc command: ["sh", "-c", "hyprctl activewindow -j | jq -r 'if .floating then \"Floating\" elif .fullscreen == 1 then \"Fullscreen\" else \"Tiled\" end'"] stdout: SplitParser { onRead: data => { if (data && data.trim()) currentLayout = data.trim() } } Component.onCompleted: running = true } // CPU Temp Process { id: cpuTempProc command: ["sh", "-c", "sensors | awk '/Tctl:/ {print $2}'"] stdout: SplitParser { onRead: data => { if (data && data.length > 0) cpuTemp = data.trim() } } } // Timers Timer { interval: 5000; running: true; repeat: true onTriggered: { connectionProc.running = true } } // UpTime Timer Timer { interval: 60000; running: true; repeat: true onTriggered: { upTimeProc.running = true } } // SysEssentials Timer Timer { interval: 2000; running: true; repeat: true onTriggered: { cpuProc.running = true; memProc.running = true; diskProc.running = true volProc.running = true; cpuTempProc.running = true; powerProfileProc.running = true } } // Weather Timer Timer { interval: 3600000; running: true; repeat: true; onTriggered: { console.log("Weather fetched at: " + new Date().toString()) weatherProc.running = true } } Connections { target: Hyprland function onRawEvent(event) { windowProc.running = true; layoutProc.running = true } } Timer { interval: 200; running: true; repeat: true onTriggered: { windowProc.running = true; layoutProc.running = true } } Variants { model: Quickshell.screens PanelWindow { property var modelData screen: modelData anchors { top: true; left: true; right: true } implicitHeight: 30 color: root.colBg Rectangle { anchors.fill: parent color: root.colBg RowLayout { anchors.fill: parent; spacing: 0 Item { width: 8 } // Arch Icon Rectangle { Layout.preferredWidth: 24; Layout.preferredHeight: 24; color: "transparent" Image { anchors.fill: parent source: "file:///home/subh/.config/quickshell/icons/arch.png" fillMode: Image.PreserveAspectFit } } Item { width: 8 } // Workspaces Repeater { model: 9 Rectangle { Layout.preferredWidth: 20; Layout.preferredHeight: parent.height; color: "transparent" property var workspace: Hyprland.workspaces.values.find(ws => ws.id === index + 1) ?? null property bool isActive: Hyprland.focusedWorkspace?.id === (index + 1) property bool hasWindows: workspace !== null Text { text: index + 1 color: parent.isActive ? root.colCyan : (parent.hasWindows ? root.colFg : root.colMuted) font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true anchors.centerIn: parent } Rectangle { width: 20; height: 3 color: parent.isActive ? root.colPurple : "transparent" anchors.horizontalCenter: parent.horizontalCenter; anchors.bottom: parent.bottom } MouseArea { anchors.fill: parent onClicked: Hyprland.dispatch("workspace " + (index + 1)) } } } // Separator Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.leftMargin: 8; Layout.rightMargin: 8; color: root.colMuted } // Layout Text { text: currentLayout; color: root.colFg; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.leftMargin: 8; Layout.rightMargin: 8; color: root.colMuted } Text { text: "󰦖 " + upTime; color: root.colCyan; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.leftMargin: 8; Layout.rightMargin: 8; color: root.colMuted } // Window Title Text { text: activeWindow; color: root.colPurple; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true Layout.fillWidth: true; Layout.leftMargin: 8; elide: Text.ElideRight; maximumLineCount: 1 } RowLayout { id: weatherRow spacing: 10 Text { text: weatherIcon color: root.colYellow font.pixelSize: 18 font.family: root.fontFamily font.bold: true } Text { text: weatherTemp font.family: root.fontFamily font.pixelSize: root.fontSize color: root.colYellow font.bold: true } Text { text: weatherPrecip font.family: root.fontFamily font.pixelSize: root.fontSize color: root.colGreen font.bold: true } Text { text: weatherWind font.family: root.fontFamily font.pixelSize: root.fontSize color: root.colBlue font.bold: true Layout.rightMargin: 8 } } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: " " + cpuTemp; color: tempColor; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: " " + cpuUsage + "%"; color: root.colPurple; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: " " + memUsage; color: root.colCyan; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: " " + diskUsage; color: root.colBlue; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: netConnection; color: root.colBlue; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 4 } // netspeed RowLayout { id: netSpeedRow visible: root.netConnection == "󰤨" spacing: 0 Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16 Layout.leftMargin: 8; Layout.rightMargin: 8 color: root.colMuted } Text { id: netSpeed color: root.colRed font.pixelSize: 15 font.family: root.fontFamily font.bold: true Layout.rightMargin: 8 Process { id: netProc command: ["bash", "/opt/scripts/netspeed.sh", "wlp8s0"] running: root.netConnection == "󰤨" stdout: SplitParser { onRead: data => netSpeed.text = data.trim() } } } } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } Text { text: " " + volumeLevel + "%"; color: root.colPurple; font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 } Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16; Layout.rightMargin: 8; color: root.colMuted } // Clock Text { id: clockText text: Qt.formatDateTime(new Date(), "ddd, MMM dd - HH:mm") color: root.colFg font.pixelSize: root.fontSize; font.family: root.fontFamily; font.bold: true; Layout.rightMargin: 8 Timer { interval: 1000; running: true; repeat: true onTriggered: clockText.text = Qt.formatDateTime(new Date(), "ddd, MMM dd - HH:mm:ss") } } RowLayout { id: notifRow visible: root.notificationCount > 0 spacing: 0 Rectangle { Layout.preferredWidth: 1; Layout.preferredHeight: 16 Layout.leftMargin: 8; Layout.rightMargin: 8 color: root.colMuted } Text { text: "󰂚 " + root.notificationCount color: root.colYellow font.pixelSize: root.fontSize font.family: root.fontFamily font.bold: true MouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: (mouse) => { if (mouse.button === Qt.RightButton) { clearAllProc.running = true; } else { showHistoryProc.running = true; } } } } } Item { width: 8 } } } } } }