Remove legacy bar widgets
This commit is contained in:
@@ -16,7 +16,6 @@ import qs.Commons
|
|||||||
// API is a subset of Common.PopupCard: anchorItem, owner, bar, open,
|
// API is a subset of Common.PopupCard: anchorItem, owner, bar, open,
|
||||||
// padding, margin, contentWidth/Height, centerOnBar, default contentItem.
|
// padding, margin, contentWidth/Height, centerOnBar, default contentItem.
|
||||||
// Missing on purpose (for now): triggerMode ("hover"), containsMouse.
|
// 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
|
// Positioning: full-screen layer-shell with the card placed inside at
|
||||||
// `cardOrigin`. We use the bar window's height/width for the perpendicular
|
// `cardOrigin`. We use the bar window's height/width for the perpendicular
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ Example `shell.json` (bar subtree only shown):
|
|||||||
| `omarchy.indicators` | Manual state indicators | left = indicator action |
|
| `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.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-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.tray` | System tray | hover = reveal drawer · right on chevron = manage |
|
||||||
| `omarchy.weather` | Weather icon + popup with forecast | left = popup · right = full notification |
|
| `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 |
|
| `omarchy.microphone` | Mic icon + scroll volume | left = mute toggle · middle = audio panel · scroll = source volume |
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -258,7 +258,7 @@ HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar show | jq -e '
|
|||||||
pass "shell config shows only bar json"
|
pass "shell config shows only bar json"
|
||||||
|
|
||||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" omarchy-config-shell-bar list --json | jq -e '
|
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")
|
all(.[]; .id != "omarchy.tailscale")
|
||||||
' >/dev/null
|
' >/dev/null
|
||||||
pass "shell config lists addable bar widgets"
|
pass "shell config lists addable bar widgets"
|
||||||
|
|||||||
Reference in New Issue
Block a user