From 49286d0e66b22d6b91e21c0f8c8fe8bd1a6ce064 Mon Sep 17 00:00:00 2001 From: Spencer Bull Date: Thu, 17 Sep 2026 21:07:08 -0500 Subject: [PATCH] Place Elsewhen immediately before the center clock --- config/omarchy/shell.json | 6 +-- default/agents/skills/omarchy/plugins.md | 4 +- docs/omarchy-shell.md | 11 +----- migrations/1789581661.sh | 10 ++--- shell/README.md | 11 +----- test/shell.d/config-test.sh | 14 +++++-- .../elsewhen-default-migration-test.sh | 37 ++++++++++++------- 7 files changed, 45 insertions(+), 48 deletions(-) diff --git a/config/omarchy/shell.json b/config/omarchy/shell.json index 64cc4075..b8aa5de4 100644 --- a/config/omarchy/shell.json +++ b/config/omarchy/shell.json @@ -21,6 +21,9 @@ { "id": "omarchy.indicators" }, + { + "id": "omacom.elsewhen" + }, { "id": "omarchy.clock", "format": "dddd HH:mm", @@ -38,9 +41,6 @@ } ], "right": [ - { - "id": "omacom.elsewhen" - }, { "id": "omarchy.tray" }, diff --git a/default/agents/skills/omarchy/plugins.md b/default/agents/skills/omarchy/plugins.md index bf1033b3..1c58c83a 100644 --- a/default/agents/skills/omarchy/plugins.md +++ b/default/agents/skills/omarchy/plugins.md @@ -13,9 +13,7 @@ inside a single long-running Quickshell process (`omarchy-shell`). $OMARCHY_PATH/config/omarchy/shell.json # Canonical defaults ``` -Packaged plugins such as Elsewhen (`elsewhen` package) update with `omarchy update` and are removed with pacman; -`omarchy plugin update` and `omarchy plugin remove` refuse them and name the -package. +Packaged plugins such as Elsewhen (`elsewhen` package) update with `omarchy update` and are removed with pacman; `omarchy plugin update` and `omarchy plugin remove` refuse them and name the package. The shell hot-reloads `shell.json` on save — no restart needed for layout changes. `idle.screensaver` and `idle.lock` are seconds since user idle began. diff --git a/docs/omarchy-shell.md b/docs/omarchy-shell.md index 18a61896..dd8cc18a 100644 --- a/docs/omarchy-shell.md +++ b/docs/omarchy-shell.md @@ -90,16 +90,7 @@ The lower-level IPC methods remain available through `omarchy-shell shell ...`. ## Packaged plugins -A default plugin can ship as its own Arch package instead of in the Omarchy -checkout: Elsewhen (`omacom.elsewhen`) is the `elsewhen` package. pacman installs them at -`/usr/share/omarchy/plugins//`, a root the shell scans between -`$OMARCHY_PATH/shell/plugins` and `~/.config/omarchy/plugins`. A packaged -`omarchy.*` id is trusted like a bundled plugin and loads by default; any other -packaged id behaves like an installed plugin. Precedence is bundled, then -packaged, then user, so a checkout under `omarchy dev link` overrides the -package. Packaged plugins update through `omarchy update` and leave through -pacman; `omarchy plugin update` and `omarchy plugin remove` refuse them and -name the package, and Setup › Plugins › Remove does not list them. +A default plugin can ship as its own Arch package instead of in the Omarchy checkout: Elsewhen (`omacom.elsewhen`) is the `elsewhen` package. pacman installs it at `/usr/share/omarchy/plugins//`, a root the shell scans between `$OMARCHY_PATH/shell/plugins` and `~/.config/omarchy/plugins`. A packaged `omarchy.*` id is trusted like a bundled plugin and loads by default; any other packaged id behaves like an installed plugin. Precedence is bundled, then packaged, then user, so a checkout under `omarchy dev link` overrides the package. Packaged plugins update through `omarchy update` and leave through pacman; `omarchy plugin update` and `omarchy plugin remove` refuse them and name the package, and Setup › Plugins › Remove does not list them. ## IPC diff --git a/migrations/1789581661.sh b/migrations/1789581661.sh index fd5d30be..163deb9c 100644 --- a/migrations/1789581661.sh +++ b/migrations/1789581661.sh @@ -50,8 +50,8 @@ if [[ -e $checkout || -L $checkout ]]; then fi fi -# The widget opens the right section of the default bar, just before the -# tray, which a machine without a shell.json takes on as soon as the shell +# The widget sits just before the clock in the center of the default bar, +# which a machine without a shell.json takes on as soon as the shell # restarts. A customized bar gets the entry written into its file rather than # placed over IPC: the shell this runs under cannot see a widget its scan # never reached and would refuse it, whereas the file it hot-reloads carries @@ -76,10 +76,10 @@ commit "$NORMALIZE | $entry_id"' def insert_at($section; $index): .bar.layout[$section] = .bar.layout[$section][:$index] + [{id: "omacom.elsewhen"}] + .bar.layout[$section][$index:]; . as $config - | (["left", "center", "right"] | map(select($config.bar.layout[.] | ids | index("omarchy.tray") != null)) | first) as $section + | (["left", "center", "right"] | map(select($config.bar.layout[.] | ids | index("omarchy.clock") != null)) | first) as $section | if $section != null then - insert_at($section; .bar.layout[$section] | ids | index("omarchy.tray")) + insert_at($section; .bar.layout[$section] | ids | index("omarchy.clock")) else - insert_at("right"; 0) + insert_at("center"; 0) end ' diff --git a/shell/README.md b/shell/README.md index 23a25ca6..53425139 100644 --- a/shell/README.md +++ b/shell/README.md @@ -142,16 +142,7 @@ You can still drop a plugin in without git: ### Packaged plugins -Some default plugins ship as their own Arch package rather than in this -checkout: Elsewhen (`omacom.elsewhen`) is the `elsewhen` package. pacman installs such a plugin, -root-owned, at `/usr/share/omarchy/plugins//`, and -the shell scans that root between its bundled plugins and the user's. A -packaged `omarchy.*` id is trusted exactly like a bundled one; a packaged -plugin under any other id is treated like a user plugin. They update with -`omarchy update` and are removed with pacman, so `omarchy plugin update` and -`omarchy plugin remove` refuse them and name the package instead. A bundled -copy in `$OMARCHY_PATH/shell/plugins` wins over the packaged one, which is how -a packaged plugin is developed under `omarchy dev link`. +Some default plugins ship as their own Arch package rather than in this checkout: Elsewhen (`omacom.elsewhen`) is the `elsewhen` package. pacman installs such a plugin, root-owned, at `/usr/share/omarchy/plugins//`, and the shell scans that root between its bundled plugins and the user's. A packaged `omarchy.*` id is trusted exactly like a bundled one; a packaged plugin under any other id is treated like a user plugin. They update with `omarchy update` and are removed with pacman, so `omarchy plugin update` and `omarchy plugin remove` refuse them and name the package instead. A bundled copy in `$OMARCHY_PATH/shell/plugins` wins over the packaged one, which is how a packaged plugin is developed under `omarchy dev link`. The lower-level IPC equivalents remain available via `omarchy-shell shell rescanPlugins`, `omarchy-shell shell enablePlugin '{}'`, and `omarchy-shell shell listPlugins`. diff --git a/test/shell.d/config-test.sh b/test/shell.d/config-test.sh index d9086d44..1cd47e33 100755 --- a/test/shell.d/config-test.sh +++ b/test/shell.d/config-test.sh @@ -33,6 +33,15 @@ jq -e ' ' "$ROOT/config/omarchy/shell.json" >/dev/null pass "default center anchor exists in center layout" +jq -e ' + def ids: map(.id // .); + (.bar.layout.center | ids) as $ids | + ($ids | index("omacom.elsewhen")) as $elsewhen | + ($ids | index("omarchy.clock")) as $clock | + $elsewhen != null and $clock == $elsewhen + 1 +' "$ROOT/config/omarchy/shell.json" >/dev/null +pass "default center layout puts elsewhen immediately before the clock" + jq -e ' any(.bar.layout.center[]; (.id // .) == "omarchy.clock" and (.formatAlt // "") == "d MMMM \u0027W\u0027ww yyyy") ' "$ROOT/config/omarchy/shell.json" >/dev/null @@ -41,12 +50,11 @@ pass "default clock date format has no leading zero" jq -e ' def ids: map(.id // .); (.bar.layout.right | ids) as $ids | - ($ids | index("omacom.elsewhen")) as $elsewhen | ($ids | index("omarchy.tray")) as $tray | ($ids | index("omarchy.agents")) as $agents | - $elsewhen == 0 and $tray == 1 and $agents == $tray + 1 + $tray == 0 and $agents == $tray + 1 ' "$ROOT/config/omarchy/shell.json" >/dev/null -pass "default right layout opens with elsewhen and the tray, then agents" +pass "default right layout opens with the tray, then agents" ROOT="$ROOT" python3 <<'PY' import json diff --git a/test/shell.d/elsewhen-default-migration-test.sh b/test/shell.d/elsewhen-default-migration-test.sh index 438ba1d3..89585f22 100644 --- a/test/shell.d/elsewhen-default-migration-test.sh +++ b/test/shell.d/elsewhen-default-migration-test.sh @@ -89,14 +89,14 @@ run_migration grep -Fxq elsewhen "$CALL_LOG" || fail "migration installs the elsewhen package" "$(cat "$CALL_LOG")" pass "migration installs the elsewhen package" -[[ $(ids right) == '["omacom.elsewhen","omarchy.tray","omarchy.agents","omarchy.power"]' ]] || - fail "migration puts the widget just before the tray" "$(cat "$config")" -pass "migration puts the widget just before the tray" +[[ $(ids center) == '["omacom.elsewhen","omarchy.clock"]' && $(ids right) == '["omarchy.tray","omarchy.agents","omarchy.power"]' ]] || + fail "migration puts the widget just before the center clock" "$(cat "$config")" +pass "migration puts the widget just before the center clock" -[[ $(jq -c '.bar.layout.right[2]' "$config") == '{"id":"omarchy.agents","syncMode":"On"}' ]] || +[[ $(jq -c '.bar.layout.right[1]' "$config") == '{"id":"omarchy.agents","syncMode":"On"}' ]] || fail "migration keeps the settings of its neighbours" "$(cat "$config")" -[[ $(jq -c '.bar.layout.center[0]' "$config") == '{"format":"HH:mm","id":"omarchy.clock"}' ]] || - fail "migration leaves other sections alone" "$(cat "$config")" +[[ $(jq -c '.bar.layout.center[1]' "$config") == '{"format":"HH:mm","id":"omarchy.clock"}' ]] || + fail "migration keeps the clock settings" "$(cat "$config")" pass "migration leaves the rest of the layout alone" grep -q 'shell rescanPlugins' "$SHELL_CALLS" && grep -q 'shell reloadConfig' "$SHELL_CALLS" || @@ -117,17 +117,17 @@ cat >"$config" <<'JSON' } JSON run_migration -[[ $(ids center) == '["omarchy.clock","omacom.elsewhen","omarchy.tray"]' && $(ids right) == '["omarchy.power"]' ]] || - fail "migration follows the tray into another section and reads string entries" "$(cat "$config")" -pass "migration follows the tray into another section and reads string entries" +[[ $(ids center) == '["omacom.elsewhen","omarchy.clock","omarchy.tray"]' && $(ids right) == '["omarchy.power"]' ]] || + fail "migration reads string clock entries" "$(cat "$config")" +pass "migration reads string clock entries" cat >"$config" <<'JSON' { "version": 1, "bar": { "layout": { "right": [{ "id": "omarchy.agents" }, { "id": "omarchy.power" }] } } } JSON run_migration -[[ $(ids right) == '["omacom.elsewhen","omarchy.agents","omarchy.power"]' ]] || - fail "migration prepends to the right section when the tray is off the bar" "$(cat "$config")" -pass "migration prepends to the right section when the tray is off the bar" +[[ $(ids center) == '["omacom.elsewhen"]' && $(ids right) == '["omarchy.agents","omarchy.power"]' ]] || + fail "migration prepends to the center section when the clock is off the bar" "$(cat "$config")" +pass "migration prepends to the center section when the clock is off the bar" cat >"$config" <<'JSON' { @@ -141,6 +141,15 @@ run_migration fail "migration leaves a widget the user already placed where it is" "$(cat "$config")" pass "migration leaves a widget the user already placed where it is" +# A customized clock keeps its section and settings; insert only its neighbour. +for section in left right; do + jq -n --arg section "$section" '{version: 1, bar: {layout: {center: ["omarchy.weather"], ($section): ["omarchy.menu", {id: "omarchy.clock", format: "HH:mm"}]}}}' >"$config" + run_migration + [[ $(ids "$section") == '["omarchy.menu","omacom.elsewhen","omarchy.clock"]' && $(ids center) == '["omarchy.weather"]' ]] || + fail "migration follows a clock customized into $section" "$(cat "$config")" + pass "migration follows a clock customized into $section" +done + # ------------------------------------------------------------- edge cases rm -f "$config" run_migration @@ -156,7 +165,7 @@ cat >"$config" <<'JSON' { "version": 1, "bar": { "layout": { "right": [{ "id": "omarchy.tray" }, { "id": "omarchy.agents" }] } } } JSON SHELL_STATUS=1 run_migration -[[ $(ids right) == '["omacom.elsewhen","omarchy.tray","omarchy.agents"]' ]] || +[[ $(ids center) == '["omacom.elsewhen"]' && $(ids right) == '["omarchy.tray","omarchy.agents"]' ]] || fail "migration places the widget with no shell running" "$(cat "$config")" pass "migration places the widget with no shell running" @@ -201,7 +210,7 @@ JSON } assert_widget_placed() { - [[ $(ids right) == '["omacom.elsewhen","omarchy.tray","omarchy.power"]' ]] || + [[ $(ids center) == '["omacom.elsewhen"]' && $(ids right) == '["omarchy.tray","omarchy.power"]' ]] || fail "$1 still gets the widget" "$(cat "$config")" }