Text.implicitWidth/Height can be fractional. Passing those values
straight to the PopupWindow rounded the Wayland surface down, clipping
the 1px right/bottom border of the bubble.
Same logic as the waybar/mako sweep: migration 1778321093 converted the
user's top-level hypr configs (autostart/bindings/hyprland/input/
looknfeel/monitors + envs + apps/*) from hyprlang `.conf` to Lua, so
any earlier migration that seds those files is editing a path that no
longer exists on the new layout.
These were already applied on existing systems and skipped on fresh
installs (preflight marks them done before they would run), so the
change is purely repo cleanliness — the migrations dir stops mentioning
files the new omarchy doesn't have.
Deleted 18 migrations that only touched dead .conf paths:
1754389057 1755870033 1757866485 1757877123 1757877852 1760462260
1763386443 1767138576 1769543550 1770159912 1770375655 1771606249
1771847961 1772293693 1776410469 1776781957 1777620904 1778008689
Stripped dead .conf sed/cp blocks from 5 mixed migrations whose
remaining work still matters (webapp launcher fixup, uwsm env/term
config, xdg-terminal-exec install, Obsidian flags relocation, swayosd
systemd service):
1755507891 1758019332 1762121828 1776434586 1778171768
The four genuinely-alive .conf files (hyprlock.conf, hypridle.conf,
xdph.conf, hyprsunset.conf) are untouched. The converter migration
(1778321093) is untouched. The lua-targeting migration 1757879836 is
untouched.
The dev -> omarchy-shell flip migration (1778743515.sh) uninstalls
waybar and mako and moves both user-config dirs aside, so any older
migration that tweaks ~/.config/waybar/ or invokes
omarchy-{restart,refresh}-waybar / omarchy-restart-mako is editing
something that's about to be removed.
These migrations are already marked applied on existing systems and
skipped on fresh installs (preflight touches every migration name into
the state dir before they would run), so removing/editing them is a
no-op for anyone currently on omarchy. What it does fix is the repo
itself referring to commands that no longer exist on disk.
Deleted 26 migrations that were entirely waybar/mako tweaks:
1752793122 1754228071 1754331529 1756371020 1757279511 1757511571
1760693222 1760787158 1761269603 1763409505 1763560161 1763634099
1763653692 1764067068 1767227973 1767685679 1767716691 1768270644
1771602477 1771602647 1775208227 1777017528 1777464602 1777578316
1778139028 1778539119
Stripped the waybar/mako bits from 10 mixed migrations whose real work
is still relevant (impala install, light themes, wiremix, tzupdate,
xdg-terminal-exec, bluetui, terminal app-ids, voxtype GPU, walker
toggle):
1751887718 1752725616 1752896442 1753495989 1762121828 1762417304
1763386443 1773506226 1775241210 1778405462
Two leftover spots still pointed at command names that were renamed in
this branch:
- default/quickshell/omarchy-shell/README.md:124 said
`omarchy restart quickshell` (renamed to `omarchy restart shell`).
- config/hypr/bindings.lua:35 had a commented-out example using bare
`omarchy-menu`. The wrapper still works that way for now, but the
canonical hot path is `omarchy-shell-ipc menu toggle root` \u2014 update
the example so users copying it learn the right pattern.
`omarchy-shell-ipc menu toggle root` is what the keybinds use \u2014 it
skips the omarchy CLI dispatch hop and stays sub-ms. But humans don't
want to type that. New tiny wrapper restores `omarchy menu …` as the
CLI entry point:
omarchy menu → toggle root (bare invocation)
omarchy menu toggle [route] → toggle, route defaults to root
omarchy menu summon [route] → always open
omarchy menu close → close if open
omarchy menu refresh → re-parse the menu JSONCs
omarchy menu ping → health check
Internally each verb just execs `omarchy-shell-ipc menu …`. The
omarchy-CLI dispatcher overhead measures ~2ms on top of the direct IPC
path (32ms → 34ms keybind-to-visible), so the wrapper is fine for any
human-typed invocation; keybinds and the bar icon stay on
omarchy-shell-ipc to keep that ~30ms hot path.
Sibling `omarchy menu file`, `omarchy menu input`, etc. still resolve
through their own bins \u2014 the dispatcher picks the longest matching
prefix, so longer routes ("omarchy menu file") win over the bare
"omarchy menu" entry.
The old bash bin short-circuited with close_visible_quickshell_menu at
the top of open_quickshell_menu, so pressing any menu keybind while the
menu was open just closed it. The IPC path I introduced summoned every
time, so keyboard shortcuts couldn't dismiss \u2014 only outside clicks did
(which is why the bar icon appeared to toggle: clicking it while the
menu was open hit the menu's outer-click MouseArea, not the icon).
Add a menu.toggle IPC method:
- if root.opened: cancel() and return "closed"
- otherwise: behaves exactly like summon
Switch every Hyprland binding and the two bar-icon click handlers
(omarchy logo, battery right-click \u2192 power menu) to toggle. summon stays
as the always-open primitive for callers that want explicit summon
semantics (rare \u2014 right now nothing internal uses it).
With bin/omarchy-menu gone there's no caller that summons the menu by
writing a JSON tempfile and polling a done file. Drop everything that
existed only to support that handshake:
- menuJsonFile / menuJsonFileView / loadMenuJson / openMenu(json,...)
- pendingSelectionFile / pendingDoneFile / selectionFile / doneFile
- mergeProviderJson (the JSON-wrapper for provider output)
- applyProc / releaseProc / doneFilesToRelease / finishDoneFile /
releaseNextDoneFile / resetRequest / requestActive / closeMenu
- the menuBin property pointing at the deleted bin
applySelected is now four lines (close + execDetached); cancel is two
(close + clear filter). open() takes either {menu: id} or a bare initial
menu name, and hands off to openExistingMenu which uses the cached items
from the JSONC FileViews.
Net: 91 lines smaller, no perf change.
The shell now owns the menu — both data and dispatch. The 821-line bash
bin was carrying the open path (cold spawn + jq pipeline + tempfile dance
+ IPC + poll) and a grab-bag of helpers that only existed inside it. Both
go away in this commit.
New bins for the few composite helpers that were genuinely worth keeping:
- omarchy-install-app NAME PKG
- omarchy-install-and-launch NAME PKG DESKTOP_ID
- omarchy-install-font LABEL PKG FAMILY
- omarchy-launch-config-editor PATH
- omarchy-reminder-set-interactive
- omarchy-capture-screenrecording-with-webcam
Sweep through default/omarchy/omarchy-menu.jsonc rewrites:
- present_terminal X -> omarchy-launch-floating-terminal-with-presentation X
- install_terminal X -> omarchy-launch-floating-terminal-with-presentation 'omarchy-install-terminal X'
- install / install_and_launch / install_font / open_in_editor -> new bins above
- terminal X -> xdg-terminal-exec --app-id=org.omarchy.terminal X
- default_browser_is X -> [[ "$(omarchy-default-browser)" == "X" ]]
- default_terminal_is X / default_editor_is X / haptic_touchpad_is X same shape
- $(hypr_config_file X) -> ~/.config/hypr/X.lua
- show_custom_reminder_input -> omarchy-reminder-set-interactive
- screenrecord_with_webcam -> omarchy-capture-screenrecording-with-webcam
- stop_active_screenrecording -> omarchy-capture-screenrecording --stop-recording
Hyprland bindings switch from `omarchy-menu X` to
`omarchy-shell-ipc menu summon X` (the keybind hot path now skips bash
entirely). The Bar.qml omarchy widget and the battery right-click do the
same. ALT+PRINT becomes a one-liner: stop the recording if one is going,
otherwise summon the screenrecord submenu.
Measured: keybind-to-visible is ~30ms (was ~235ms). The shell's plugin
keepLoaded:true stops being theoretical \u2014 the menu data lives in memory
across opens, and the only work between keypress and paint is the IPC
roundtrip and the layer-shell window mount.
omarchy-menu used to spawn an 821-line bash bin on every keybind: 11 jq
invocations against omarchy-menu.jsonc, mktemp dance, summon, poll. The
shell waited ~235ms (keybind to visible) before painting the first row.
The bar plugin host is already a persistent process with the menu plugin
loaded (keepLoaded: true) — it just wasn't allowed to own the menu data.
Now it does:
- parseMenuJsonc / normalizeItem ports the bash bin's jq pipeline to
JS: strip // comments + trailing commas, infer parent from dotted
ids, dedupe keyword tokens across id/aliases/keywords, fill defaults.
- Two FileViews with watchChanges: true on the default and user
extension JSONCs. Edit either file and the in-memory item map
refreshes without a restart.
- IpcHandler exposes menu.summon(initialMenu) / refresh() / close() /
ping(). summon resolves aliases the way the old bash route_target
did, including the leaf-alias-is-an-action shortcut.
- Action dispatch is now direct: when summoned via IPC (no selection
or done file), Quickshell.execDetached(['bash','-lc', action]) runs
the action and the menu closes. The legacy tempfile dance is kept
only for the duration of the migration window.
- provider sub-menus (fonts, power-profiles) are inline: tab-delimited
bash one-liner per provider, parsed by mergeProviderRows.
- when:/checked: bash expressions are batched into one Process at
shell startup (and again whenever the JSONCs change). The menu
opens instantly; visibility/check marks settle within ~50ms.
Measured: keybind-to-visible via the new IPC path is ~30ms (was ~235ms).
The bash bin still works for now and is removed in the next commit.
Replace the mako-only migration with a single "complete the flip"
migration that handles everything needed to bring a dev-channel user
onto omarchy-shell:
- install quickshell if it isn't already on the box
- stop and uninstall mako; pacman -Rns deletes the .service unit too,
so D-Bus activation can't conjure it back into existence
- stop and uninstall waybar with the same uninstall-not-mask approach
- move ~/.config/{mako,waybar} aside (timestamped backup) rather than
rm -rf, so anyone with hand-tuned rules can mine them
- clear the stale toggle-state markers
- call omarchy-restart-shell so the bar and notification daemon come
up mid-session without a relog
Drop migrations/1778715864.sh: shell.json hasn't shipped to any user
yet, so a migration removing widgets nobody has is dead code.
- omarchy-bar-settings.lua is gone: the Hyprland rules it carried for
the old standalone bar-settings window no longer match anything,
since settings is now a panel plugin summoned via IPC. The still-
needed "Widget settings" sub-dialog rules move into
omarchy-shell.lua next to the existing "Omarchy Settings" rules.
- plugins README documents the `bar` plugin kind so third-party
plugin authors aren't surprised to see it on the first-party
omarchy.bar manifest. The note also calls out that they should ship
`bar-widget`s, not replace the host bar.
- omarchy-style-bar-position seeds from shell-defaults.json before
mutating, so a user without a shell.json (or with a malformed one)
no longer ends up with a stub config that blanks the bar layout.