Fix theme swatches, bar sizing, and show 9 workspaces
Claude-Session: https://claude.ai/code/session_014ADhvRXuiTvrXSbConxUey
This commit is contained in:
+28
-2
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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
@@ -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
@@ -14,7 +14,7 @@
|
||||
"id": "omarchy.menu"
|
||||
},
|
||||
{
|
||||
"id": "omarchy.workspaces"
|
||||
"id": "blob.workspaces"
|
||||
}
|
||||
],
|
||||
"center": [
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user