Fix theme swatches, bar sizing, and show 9 workspaces

Claude-Session: https://claude.ai/code/session_014ADhvRXuiTvrXSbConxUey
This commit is contained in:
2026-08-19 14:22:21 -04:00
parent 7eabe8bb1f
commit 85652bd0b3
9 changed files with 161 additions and 14 deletions
+28 -2
View File
@@ -491,9 +491,11 @@
}
.agent-mark {
color: @accent;
font-size: 20px;
min-width: 26px;
min-height: 26px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.agent-name {
@@ -541,14 +543,27 @@
.agent-limit-bar trough,
.agent-day-bar trough {
min-height: 3px;
border-radius: 0;
background-color: alpha(@foreground, 0.14);
}
.agent-limit-bar block,
.agent-day-bar block {
min-height: 3px;
min-width: 0;
border-radius: 0;
}
.agent-limit-bar block.filled,
.agent-day-bar block.filled {
background-color: @foreground;
}
.agent-limit-bar block.empty,
.agent-day-bar block.empty {
background-color: transparent;
}
.agent-day-row {
padding: 1px 0;
}
@@ -578,13 +593,24 @@
.agent-model-bar trough {
min-height: 22px;
border-radius: 0;
background-color: alpha(@foreground, 0.08);
}
.agent-model-bar block {
min-height: 22px;
min-width: 0;
border-radius: 0;
}
.agent-model-bar block.filled {
background-color: alpha(@foreground, 0.18);
}
.agent-model-bar block.empty {
background-color: transparent;
}
.agent-model-text {
padding: 0 8px;
}
+11 -9
View File
@@ -51,9 +51,11 @@ const EMPTY_USAGE: AgentUsage = {
const WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
const MARK_PATH = "/usr/share/omarchy/shell/plugins/agents/assets/claude.svg"
function formatTokens(tokens: number) {
if (tokens >= 1000000000) return `${(tokens / 1000000000).toFixed(2)}B`
if (tokens >= 1000000) return `${(tokens / 1000000).toFixed(2)}M`
if (tokens >= 1000000000) return `${(tokens / 1000000000).toFixed(1)}B`
if (tokens >= 1000000) return `${(tokens / 1000000).toFixed(1)}M`
if (tokens >= 1000) return `${(tokens / 1000).toFixed(1)}K`
return `${Math.round(tokens)}`
}
@@ -87,20 +89,20 @@ function formatModelName(model: string) {
.replace(/(^| )(\w)/g, (_match, space, letter) => `${space}${letter.toUpperCase()}`)
}
function formatPercent(percent: number) {
if (percent > 0 && percent < 1) return "<1%"
return `${Math.round(percent)}%`
function formatPercent(usedFraction: number) {
if (usedFraction > 0 && usedFraction < 0.01) return "<1%"
return `${Math.round(usedFraction * 100)}%`
}
function parseLimits(record: any): Limit[] {
if (!Array.isArray(record.limits)) return []
return record.limits.map((limit: any) => {
const percent = Number(limit.percent) || 0
const usedFraction = Number(limit.percent) || 0
return {
label: String(limit.label ?? "").replace(/\s*\(.*\)$/, ""),
percent,
fraction: Math.min(1, Math.max(0, percent / 100)),
percent: usedFraction,
fraction: Math.min(1, Math.max(0, usedFraction)),
resetsIn: formatResetsIn(String(limit.resetsAt ?? "")),
}
})
@@ -253,7 +255,7 @@ export function ClaudeUsageCard() {
return (
<box class="panel widget-card" vertical spacing={10}>
<box spacing={10}>
<label class="agent-mark" label={""} valign={Gtk.Align.CENTER} />
<box class="agent-mark" valign={Gtk.Align.CENTER} css={`background-image: url('${MARK_PATH}');`} />
<box vertical valign={Gtk.Align.CENTER}>
<label
class="agent-name"
+10 -1
View File
@@ -10,6 +10,15 @@ const COLUMNS = 3
type Theme = { slug: string; name: string; swatches: string[] }
const swatchProgram =
"{ key=$1; value=$2; gsub(/[ \\t]/, \"\", key); gsub(/[ \"\\t]/, \"\", value); " +
"if (value ~ /^#/) palette[key] = value } " +
"END { split(\"color1 color2 color3 color4 color5 color6\", legacy, \" \"); " +
"split(\"red green yellow blue magenta cyan\", named, \" \"); " +
"for (i = 1; i <= 6; i++) { " +
"value = (legacy[i] in palette) ? palette[legacy[i]] : ((named[i] in palette) ? palette[named[i]] : \"\"); " +
"if (value != \"\") out = (out == \"\" ? value : out \",\" value) } print out }"
const listCommand =
"{ find \"$HOME/.config/omarchy/themes\" -mindepth 1 -maxdepth 1 -type d 2>/dev/null; " +
"find \"$OMARCHY_PATH/themes\" -mindepth 1 -maxdepth 1 -type d 2>/dev/null; } | " +
@@ -17,7 +26,7 @@ const listCommand =
"[ -f \"$d/colors.toml\" ] || continue; " +
"n=$(basename \"$d\"); " +
"[ \"$n\" = blob-dynamic ] && continue; " +
"c=$(grep -E '^color[1-6] *=' \"$d/colors.toml\" | sed -E 's/^color[0-9]+ *= *\"?([^\"]*)\"?.*/\\1/' | paste -sd,); " +
"c=$(awk -F'=' '" + swatchProgram + "' \"$d/colors.toml\"); " +
"p=$(echo \"$n\" | sed -E 's/(^|-)([a-z])/\\1\\u\\2/g; s/-/ /g'); " +
"echo \"$n|$p|$c\"; " +
"done | awk -F'|' '!seen[$1]++' | sort -t'|' -k2,2"
+2
View File
@@ -203,6 +203,7 @@ check_file "$SCRIPT_DIR/hypr/hyprsunset.conf" "$HOME_DIR/.config/hypr/hyprsunset
check_file "$SCRIPT_DIR/hypr/xdph.conf" "$HOME_DIR/.config/hypr/xdph.conf" "hypr/xdph.conf" || check_status=1
check_file "$SCRIPT_DIR/omarchy/shell.json" "$HOME_DIR/.config/omarchy/shell.json" "omarchy/shell.json" || check_status=1
check_file "$SCRIPT_DIR/omarchy/extensions/omarchy-menu.jsonc" "$HOME_DIR/.config/omarchy/extensions/omarchy-menu.jsonc" "omarchy/extensions/omarchy-menu.jsonc" || check_status=1
check_file "$SCRIPT_DIR/omarchy/plugins/blob.workspaces/Workspaces.qml" "$HOME_DIR/.config/omarchy/plugins/blob.workspaces/Workspaces.qml" "omarchy/plugins/blob.workspaces" || check_status=1
check_file "$SCRIPT_DIR/omarchy/hooks/theme-set" "$HOME_DIR/.config/omarchy/hooks/theme-set" "omarchy/hooks/theme-set" || check_status=1
check_file "$SCRIPT_DIR/omarchy/themed/zen.css.tpl" "$HOME_DIR/.config/omarchy/themed/zen.css.tpl" "omarchy/themed/zen.css.tpl" || check_status=1
check_file "$SCRIPT_DIR/ags/app.ts" "$HOME_DIR/.config/ags/app.ts" "ags/app.ts" || check_status=1
@@ -267,6 +268,7 @@ backup_and_copy "$SCRIPT_DIR/branding" "$HOME_DIR/.config/omarchy/branding" "Bra
backup_and_copy "$SCRIPT_DIR/omarchy/hooks" "$HOME_DIR/.config/omarchy/hooks" "Omarchy hooks"
backup_and_copy "$SCRIPT_DIR/omarchy/themed" "$HOME_DIR/.config/omarchy/themed" "Omarchy custom templates"
backup_and_copy "$SCRIPT_DIR/omarchy/extensions" "$HOME_DIR/.config/omarchy/extensions" "Omarchy menu extensions"
backup_and_copy "$SCRIPT_DIR/omarchy/plugins" "$HOME_DIR/.config/omarchy/plugins" "Omarchy shell plugins"
backup_and_copy_file "$SCRIPT_DIR/omarchy/shell.json" "$HOME_DIR/.config/omarchy/shell.json" "Omarchy shell config"
replace_and_copy "$SCRIPT_DIR/wallpapers" "$HOME_DIR/wallpapers" "Custom wallpapers"
+13 -1
View File
@@ -11,7 +11,7 @@ Ported from the old `waybar/config.jsonc`, section for section:
| Old waybar module | shell.json widget |
| --- | --- |
| `custom/omarchy` | `omarchy.menu` |
| `hyprland/workspaces` | `omarchy.workspaces` |
| `hyprland/workspaces` | `blob.workspaces` (cloned plugin) |
| `clock` | `blob.clock` (custom module) |
| `custom/update` | `omarchy.system-update` |
| `custom/voxtype` | `omarchy.indicators` -> `Dictation` |
@@ -48,6 +48,18 @@ AGS entry points survive the move off waybar:
A command module with no `exec` key is a static icon; add `exec` and
`interval` for one that refreshes its own text.
## Cloned plugins
`plugins/blob.workspaces/` is a clone of `omarchy.workspaces`, made with
`omarchy plugin clone`. The stock widget hardcodes workspaces 1-5 as always
visible and has no setting for it, so the clone changes that list to 1-9 to
match the old waybar `persistent-workspaces`. Cloning also switches the bar
to the cloned id, which is why `shell.json` says `blob.workspaces`.
Re-clone after an Omarchy update if the upstream widget gains something worth
picking up: `omarchy plugin clone omarchy.workspaces`, then re-apply the
one-line `workspaceIds()` change.
## Editing
Dragging widgets in the bar rewrites `~/.config/omarchy/shell.json` directly.
@@ -0,0 +1,72 @@
import QtQuick
import QtQuick.Layouts
import Quickshell.Hyprland
import qs.Commons
import qs.Ui
BarWidget {
id: root
moduleName: "omarchy.workspaces"
function workspaceById(id) {
var values = Hyprland.workspaces.values
for (var i = 0; i < values.length; i++) {
if (values[i].id === id) return values[i]
}
return null
}
function workspaceIds() {
var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9]
var values = Hyprland.workspaces.values
for (var i = 0; i < values.length; i++) {
var id = values[i].id
if (id > 0 && id <= 10 && ids.indexOf(id) === -1) ids.push(id)
}
ids.sort(function(left, right) { return left - right })
return ids
}
function focusWorkspace(id) {
if (!root.bar) return
root.bar.run("hyprctl dispatch " + Util.shellQuote("hl.dsp.focus({ workspace = \"" + id + "\" })"))
}
readonly property real trailingGap: root.vertical ? 0 : Style.spaceReal(1.5)
implicitWidth: grid.implicitWidth + trailingGap
implicitHeight: grid.implicitHeight
GridLayout {
id: grid
anchors.fill: parent
anchors.rightMargin: root.trailingGap
columns: root.vertical ? 1 : root.workspaceIds().length
columnSpacing: root.vertical ? 0 : Style.space(1)
rowSpacing: root.vertical ? Style.space(2) : 0
Repeater {
model: root.workspaceIds()
WidgetButton {
required property int modelData
readonly property var workspace: root.workspaceById(modelData)
readonly property bool occupied: workspace !== null && workspace.toplevels.values.length > 0
readonly property bool focused: Hyprland.focusedWorkspace !== null && Hyprland.focusedWorkspace.id === modelData
bar: root.bar
text: focused ? "\uDB85\uDCFB" : (modelData === 10 ? "0" : String(modelData))
opacity: occupied || focused ? 1 : 0.5
horizontalMargin: 6
verticalPadding: 6
fixedWidth: root.vertical ? root.barSize : Style.space(20)
fixedHeight: root.barSize
onPressed: function() { root.focusWorkspace(modelData) }
}
}
}
}
@@ -0,0 +1,23 @@
{
"schemaVersion": 1,
"id": "blob.workspaces",
"name": "My Workspaces",
"version": "1.0.0",
"author": "Omarchy",
"description": "Workspace number indicators",
"kinds": [
"bar-widget"
],
"entryPoints": {
"barWidget": "Workspaces.qml"
},
"barWidget": {
"displayName": "My Workspaces",
"description": "Workspace number indicators",
"category": "Compositor",
"allowMultiple": false
},
"omarchy": {
"clonedFrom": "omarchy.workspaces"
}
}
+1 -1
View File
@@ -14,7 +14,7 @@
"id": "omarchy.menu"
},
{
"id": "omarchy.workspaces"
"id": "blob.workspaces"
}
],
"center": [
+1
View File
@@ -74,6 +74,7 @@ revert_dir "$HOME_DIR/.config/hypr" "Hyprland config"
revert_dir "$HOME_DIR/.config/omarchy/branding" "Branding files"
revert_dir "$HOME_DIR/.config/omarchy/hooks" "Omarchy hooks"
revert_dir "$HOME_DIR/.config/omarchy/extensions" "Omarchy menu extensions"
revert_dir "$HOME_DIR/.config/omarchy/plugins" "Omarchy shell plugins"
revert_file "$HOME_DIR/.config/omarchy/shell.json" "Omarchy shell config"
revert_dir "$HOME_DIR/wallpapers" "Custom wallpapers"
revert_dir "$HOME_DIR/scripts" "Custom scripts"