From 1db2323fd967b8bc25637d1bc75540cb7e2fb86f Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 23 Jun 2026 16:22:47 +0200 Subject: [PATCH] Remove legacy bar widgets --- shell/Ui/KeyboardPanel.qml | 1 - shell/plugins/bar/README.md | 1 - .../bar/widgets/LockKeys.manifest.json | 20 -- shell/plugins/bar/widgets/LockKeys.qml | 94 ------- .../bar/widgets/SystemStats.manifest.json | 20 -- shell/plugins/bar/widgets/SystemStats.qml | 263 ------------------ test/shell.d/config-test.sh | 2 +- 7 files changed, 1 insertion(+), 400 deletions(-) delete mode 100644 shell/plugins/bar/widgets/LockKeys.manifest.json delete mode 100644 shell/plugins/bar/widgets/LockKeys.qml delete mode 100644 shell/plugins/bar/widgets/SystemStats.manifest.json delete mode 100644 shell/plugins/bar/widgets/SystemStats.qml diff --git a/shell/Ui/KeyboardPanel.qml b/shell/Ui/KeyboardPanel.qml index e590d7f1..7b891b04 100644 --- a/shell/Ui/KeyboardPanel.qml +++ b/shell/Ui/KeyboardPanel.qml @@ -16,7 +16,6 @@ import qs.Commons // API is a subset of Common.PopupCard: anchorItem, owner, bar, open, // padding, margin, contentWidth/Height, centerOnBar, default contentItem. // Missing on purpose (for now): triggerMode ("hover"), containsMouse. -// Hover-mode popups (system-stats) need extra plumbing before migrating. // // Positioning: full-screen layer-shell with the card placed inside at // `cardOrigin`. We use the bar window's height/width for the perpendicular diff --git a/shell/plugins/bar/README.md b/shell/plugins/bar/README.md index 437a289a..9afe9e40 100644 --- a/shell/plugins/bar/README.md +++ b/shell/plugins/bar/README.md @@ -61,7 +61,6 @@ Example `shell.json` (bar subtree only shown): | `omarchy.indicators` | Manual state indicators | left = indicator action | | `omarchy.notifications` | Bell with badge + popup with recent notifications, DND toggle | left = popup · right = toggle DND | | `omarchy.system-update` | Available update indicator | left = update | -| `omarchy.system-stats` | Inline CPU + memory sparklines, popup with detail | left = popup · right = terminal | | `omarchy.tray` | System tray | hover = reveal drawer · right on chevron = manage | | `omarchy.weather` | Weather icon + popup with forecast | left = popup · right = full notification | | `omarchy.microphone` | Mic icon + scroll volume | left = mute toggle · middle = audio panel · scroll = source volume | diff --git a/shell/plugins/bar/widgets/LockKeys.manifest.json b/shell/plugins/bar/widgets/LockKeys.manifest.json deleted file mode 100644 index 6db4f0fb..00000000 --- a/shell/plugins/bar/widgets/LockKeys.manifest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "schemaVersion": 1, - "id": "omarchy.lock-keys", - "name": "Lock keys", - "version": "1.0.0", - "author": "Omarchy", - "description": "Caps / Num / Scroll lock indicators", - "kinds": [ - "bar-widget" - ], - "entryPoints": { - "barWidget": "LockKeys.qml" - }, - "barWidget": { - "displayName": "Lock keys", - "description": "Caps / Num / Scroll lock indicators", - "category": "System", - "allowMultiple": false - } -} diff --git a/shell/plugins/bar/widgets/LockKeys.qml b/shell/plugins/bar/widgets/LockKeys.qml deleted file mode 100644 index 0c5f2bc9..00000000 --- a/shell/plugins/bar/widgets/LockKeys.qml +++ /dev/null @@ -1,94 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Commons -import qs.Ui - -BarWidget { - id: root - moduleName: "omarchy.lock-keys" - - - property bool capsOn: false - property bool numOn: false - property bool scrollOn: false - property bool hideWhenOff: true - - Component.onCompleted: { - hideWhenOff = setting("hideWhenOff", true) === true - refresh() - } - - function refresh() { - if (!stateProc.running) stateProc.running = true - } - - property bool ledsAvailable: true - - Process { - id: stateProc - command: ["bash", "-lc", "read_led() { for path in /sys/class/leds/input*::$1; do if [[ -r $path/brightness ]]; then cat $path/brightness; return; fi; done; echo missing; }; read_led capslock; read_led numlock; read_led scrolllock"] - stdout: StdioCollector { - waitForEnd: true - onStreamFinished: { - var lines = String(text || "").split("\n") - var caps = String(lines[0] || "").trim() - var num = String(lines[1] || "").trim() - var scroll = String(lines[2] || "").trim() - root.capsOn = caps !== "missing" && parseInt(caps, 10) > 0 - root.numOn = num !== "missing" && parseInt(num, 10) > 0 - root.scrollOn = scroll !== "missing" && parseInt(scroll, 10) > 0 - root.ledsAvailable = caps !== "missing" || num !== "missing" || scroll !== "missing" - } - } - } - - Timer { - interval: 2000 - running: root.ledsAvailable - repeat: true - onTriggered: root.refresh() - } - - readonly property bool anyOn: capsOn || numOn || scrollOn - visible: ledsAvailable && (hideWhenOff ? anyOn : true) - - implicitWidth: vertical ? barSize : (lay.item ? lay.item.implicitWidth + Style.spacing.controlGap : 0) - implicitHeight: vertical ? (lay.item ? lay.item.implicitHeight + Style.spacing.controlGap : 0) : barSize - - Loader { - id: lay - anchors.centerIn: parent - sourceComponent: root.vertical ? colLayout : rowLayout - } - - Component { - id: rowLayout - Row { - spacing: Style.space(4) - LockGlyph { glyph: "A"; active: root.capsOn; visible: !root.hideWhenOff || root.capsOn } - LockGlyph { glyph: "1"; active: root.numOn; visible: !root.hideWhenOff || root.numOn } - LockGlyph { glyph: "S"; active: root.scrollOn; visible: !root.hideWhenOff || root.scrollOn } - } - } - - Component { - id: colLayout - Column { - spacing: Style.space(2) - LockGlyph { glyph: "A"; active: root.capsOn; visible: !root.hideWhenOff || root.capsOn } - LockGlyph { glyph: "1"; active: root.numOn; visible: !root.hideWhenOff || root.numOn } - LockGlyph { glyph: "S"; active: root.scrollOn; visible: !root.hideWhenOff || root.scrollOn } - } - } - - component LockGlyph: Text { - property string glyph: "" - property bool active: false - - text: glyph - color: active ? (root.bar ? root.bar.barForeground : Color.foreground) : Qt.rgba(0.7, 0.7, 0.7, 0.3) - font.family: root.bar ? root.bar.fontFamily : Style.font.family - font.pixelSize: Style.font.bodySmall - } -} diff --git a/shell/plugins/bar/widgets/SystemStats.manifest.json b/shell/plugins/bar/widgets/SystemStats.manifest.json deleted file mode 100644 index df619e7d..00000000 --- a/shell/plugins/bar/widgets/SystemStats.manifest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "schemaVersion": 1, - "id": "omarchy.system-stats", - "name": "System stats", - "version": "1.0.0", - "author": "Omarchy", - "description": "CPU icon \u2014 hover for graphs, click to open btop", - "kinds": [ - "bar-widget" - ], - "entryPoints": { - "barWidget": "SystemStats.qml" - }, - "barWidget": { - "displayName": "System stats", - "description": "CPU icon \u2014 hover for graphs, click to open btop", - "category": "System", - "allowMultiple": false - } -} diff --git a/shell/plugins/bar/widgets/SystemStats.qml b/shell/plugins/bar/widgets/SystemStats.qml deleted file mode 100644 index 0d10d1ad..00000000 --- a/shell/plugins/bar/widgets/SystemStats.qml +++ /dev/null @@ -1,263 +0,0 @@ -import QtQuick -import Quickshell -import Quickshell.Io -import qs.Ui -import qs.Commons - -BarWidget { - id: root - moduleName: "omarchy.system-stats" - - - property real cpuPercent: 0 - property real memPercent: 0 - property var cpuHistory: [] - property var memHistory: [] - property real loadAvg: 0 - - property var prevCpu: ({ idle: 0, total: 0 }) - - property bool popupOpen: false - - function close() { popupOpen = false } - - readonly property int historyLimit: 30 - - function refresh() { - if (!statsProc.running) statsProc.running = true - } - - function pushHistory(arr, value) { - var next = arr.slice() - next.push(value) - if (next.length > historyLimit) next.shift() - return next - } - - function updateCpuTotals(idle, total) { - var idleDiff = idle - prevCpu.idle - var totalDiff = total - prevCpu.total - - if (prevCpu.total > 0 && totalDiff > 0) { - var usage = (1 - idleDiff / totalDiff) * 100 - cpuPercent = Math.max(0, Math.min(100, usage)) - cpuHistory = pushHistory(cpuHistory, cpuPercent) - } - - prevCpu = { idle: idle, total: total } - } - - function updateLoad(raw) { - var n = parseFloat(String(raw || "").trim().split(/\s+/)[0]) - if (!isNaN(n)) loadAvg = n - } - - function updateStats(raw) { - var lines = String(raw || "").split("\n") - for (var i = 0; i < lines.length; i++) { - var parts = lines[i].trim().split("\t") - if (parts.length < 2) continue - if (parts[0] === "cpu") updateCpuTotals(parseInt(parts[1], 10) || 0, parseInt(parts[2], 10) || 0) - else if (parts[0] === "memory") updateMemPercent(parts[1]) - else if (parts[0] === "load") updateLoad(parts[1]) - } - } - - function updateMemPercent(raw) { - var n = parseFloat(String(raw || "").trim()) - if (!isNaN(n)) { - memPercent = Math.max(0, Math.min(100, n)) - memHistory = pushHistory(memHistory, memPercent) - } - } - - Component.onCompleted: refresh() - - Process { - id: statsProc - command: [root.bar ? root.bar.omarchyPath + "/bin/omarchy-system-stats" : "omarchy-system-stats", "--bar-widget"] - stdout: StdioCollector { - waitForEnd: true - onStreamFinished: root.updateStats(text) - } - } - - Timer { - interval: 2000 - running: true - repeat: true - onTriggered: root.refresh() - } - - readonly property color statColor: bar ? bar.barForeground : Color.foreground - - implicitWidth: button.implicitWidth - implicitHeight: button.implicitHeight - - // Hover state across the trigger button and the popup. - property bool buttonHovered: false - property bool popupHovered: popup.containsMouse - - function showPopup() { - hideTimer.stop() - popupOpen = true - } - - function scheduleHide() { - hideTimer.restart() - } - - Timer { - id: hideTimer - interval: 220 - onTriggered: { - if (!root.buttonHovered && !root.popupHovered) root.popupOpen = false - } - } - - onButtonHoveredChanged: buttonHovered ? showPopup() : scheduleHide() - onPopupHoveredChanged: popupHovered ? hideTimer.stop() : scheduleHide() - - WidgetButton { - id: button - anchors.fill: parent - bar: root.bar - text: "󰍛" - horizontalMargin: 7.5 - tooltipText: "" - - onPressed: function(b) { - if (b === Qt.LeftButton) { - root.popupOpen = false - root.bar.run("omarchy-launch-or-focus-tui btop") - } - } - } - - HoverHandler { - id: hoverHandler - target: button - onHoveredChanged: root.buttonHovered = hovered - } - - PopupCard { - id: popup - anchorItem: button - owner: root - bar: root.bar - open: root.popupOpen - triggerMode: "hover" - contentWidth: popup.fittedContentWidth(Style.space(320)) - contentHeight: popup.fittedContentHeight(detailColumn.implicitHeight) - - Column { - id: detailColumn - anchors.fill: parent - spacing: Style.space(10) - - Text { - text: "System" - color: root.bar.foreground - font.family: root.bar.fontFamily - font.pixelSize: Style.font.body - font.bold: true - } - - DetailStat { - title: "CPU" - value: Math.round(root.cpuPercent) + "%" - history: root.cpuHistory - barFg: root.bar.foreground - fontFamily: root.bar.fontFamily - width: parent.width - } - - DetailStat { - title: "Memory" - value: Math.round(root.memPercent) + "%" - history: root.memHistory - barFg: root.bar.foreground - fontFamily: root.bar.fontFamily - width: parent.width - } - - Row { - width: parent.width - spacing: Style.space(6) - Text { - text: "Load" - color: Qt.darker(root.bar.foreground, 1.5) - font.family: root.bar.fontFamily - font.pixelSize: Style.font.bodySmall - } - Text { - text: root.loadAvg.toFixed(2) - color: root.bar.foreground - font.family: root.bar.fontFamily - font.pixelSize: Style.font.bodySmall - } - } - } - } - - component DetailStat: Column { - id: detail - - property string title: "" - property string value: "" - property var history: [] - property color barFg: Color.foreground - property string fontFamily: Style.font.family - - spacing: Style.space(4) - - Row { - width: parent.width - Text { - text: detail.title - color: Qt.darker(detail.barFg, 1.4) - font.family: detail.fontFamily - font.pixelSize: Style.font.bodySmall - } - Item { width: detail.width - parent.children[0].implicitWidth - parent.children[2].implicitWidth; height: 1 } - Text { - text: detail.value - color: detail.barFg - font.family: detail.fontFamily - font.pixelSize: Style.font.bodySmall - } - } - - Canvas { - id: detailCanvas - width: parent.width - height: Style.space(40) - property var history: detail.history - onHistoryChanged: requestPaint() - - onPaint: { - var ctx = getContext("2d") - ctx.clearRect(0, 0, width, height) - if (!detail.history || detail.history.length === 0) return - - ctx.strokeStyle = detail.barFg - ctx.fillStyle = Qt.rgba(detail.barFg.r, detail.barFg.g, detail.barFg.b, 0.25) - ctx.lineWidth = 1.5 - - ctx.beginPath() - var step = width / Math.max(1, detail.history.length - 1) - for (var i = 0; i < detail.history.length; i++) { - var x = i * step - var y = height - (detail.history[i] / 100) * (height - 2) - 1 - if (i === 0) ctx.moveTo(x, y) - else ctx.lineTo(x, y) - } - ctx.stroke() - ctx.lineTo(width, height) - ctx.lineTo(0, height) - ctx.closePath() - ctx.fill() - } - } - } -} diff --git a/test/shell.d/config-test.sh b/test/shell.d/config-test.sh index 5ec6228c..480f8888 100755 --- a/test/shell.d/config-test.sh +++ b/test/shell.d/config-test.sh @@ -258,7 +258,7 @@ HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar show | jq -e ' pass "shell config shows only bar json" HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar list --json | jq -e ' - any(.[]; .id == "omarchy.system-stats" and .addable == true and .inBar == false) and + any(.[]; .id == "omarchy.keyboard-layout" and .addable == true and .inBar == false) and all(.[]; .id != "omarchy.tailscale") ' >/dev/null pass "shell config lists addable bar widgets"