With initial workspace tracking disabled, windows naturally open on the active workspace. Remove the explicit Hyprland workspace dispatch and let shell actions, shell restarts, and presentation terminals launch directly.
Long passwords used to overflow the input field and clip with no
feedback that typing was still registering. Scale the dot size and
letter spacing down as the password grows, like macOS, so every
keystroke stays visible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
omarchy-restart-shell now kills by config dir via quickshell kill and
relaunches with --no-duplicate, polling kill until every instance is
gone since kill returns without waiting and -n silently exits if one
remains. The locked-session refusal reads Hyprland monitor state alone,
which covers a hung shell holding the lock; the redundant shell IPC
probe, availability guards, and omarchy-shell path indirection are gone.
Shell IPC calls now time out (2s default, OMARCHY_SHELL_IPC_TIMEOUT to
override) so probing an unresponsive shell fails fast instead of
hanging the caller.
omarchy-hyprland-launch checks dispatch output for "ok" rather than the
exit code, which is 0 even on Lua errors, so a failed dispatch falls
through to the bash -lc fallback instead of silently launching nothing.
The Quattro upgrade cutover delegates to omarchy-restart-shell instead
of carrying its own copy of the lock check, pkill, and readiness loop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Explicit profile selections from the power panel or menu are now saved
under an ac/battery key in ~/.local/state/omarchy/powerprofiles and
reapplied on boot and on plug/unplug. Only successful, user-made
selections are persisted, so the performance/balanced defaults still
apply when nothing has been chosen.
All entry points key off the same power signal, UPower's OnBattery:
the shell reads it natively and omarchy-powerprofiles-set autodetect
queries it via busctl. This replaces the sysfs online checks, which
disagreed with the shell on desktops without power_supply entries and
lagged behind plug events on some USB-C laptops.
Plug/unplug switching moves from the udev rule into the shell's battery
service, which already receives UPower's debounced state changes, so
the udev rule and its settle-sleep workaround are gone.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hyprland can report a scale set to 3 as something like 3.0000000000000004.
The previous directional comparison treated that as above the 3 preset, so
Super+Alt+Slash (scale down) would stay at 3 instead of reaching 2.
Snap the reported scale to the nearest preset first, then step up/down.
Add a regression test for the floating-point case.
* Align MAX_SNAPSHOT_ENTRIES with Snapper retention
Snapper is configured with NUMBER_LIMIT="5", but limine-snapper-sync
also counts the freshly-created / currently-booted snapshot, so five
retained snapshots are reported as six entries and it warns on every
snapshot and update:
Snapshot limit mismatch: 6 Snapper snapshots exceed configured
MAX_SNAPSHOT_ENTRIES=5
Raise MAX_SNAPSHOT_ENTRIES to 6 (NUMBER_LIMIT + 1) so the boot-menu cap
and Snapper's retention agree and the off-by-one warning stops. (An
alternative is MAX_SNAPSHOT_ENTRIES=auto, which derives the cap from
Snapper directly; kept an explicit value here to preserve the existing
boot-menu limit.)
Co-Authored-By: Claude <noreply@anthropic.com>
* Clarify Limine snapshot limit
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
* Prevent empty drive encryption passwords
* Use sudo, quote the confirmation compare, and cover mismatches in test
The unquoted [[ $new_password == $confirmation ]] made the confirmation
a glob pattern, so a confirmation like * matched any password. And pkexec
brought nothing over the repo-standard sudo here while failing outright
in sessions without a polkit agent.
Verified against a loopback LUKS device: new key lands from stdin without
a trailing newline while the current passphrase is prompted on the tty.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: mplaczek99 <mplaczek99@gmail.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The canonical colors.toml keys are now background/foreground, including
all permutations (dark_background, darker_background, lighter_background,
dark_foreground, light_foreground, bright_foreground). The old short
names are gone entirely, not kept as aliases; legacy alacritty-generated
themes still resolve through the ANSI color0/color7 fallback.
Theme files are also regrouped: accent/selection/muted first, then the
backgrounds, then the foregrounds, then the named colors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Existing quattro installs get sof-firmware, the Mesa Vulkan drivers,
the tmux terminal-features and pane-binding fixes, and the XPS 13 text
scaling via migration, while Omarchy 4 upgraders get the same hardware
support and scaling through omarchy-upgrade-to-quattro.
The Vulkan driver backfill adapts da46ad85 from master.
Co-authored-by: Sai Sridhar <tarrasridhar1154@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pacman -Q resolves provider names, so dropping a virtual package could
remove whichever package provides it. Read pacman -Qq once and match
requested names exactly, ignoring providers and duplicate arguments.
Ports the provider-ignoring semantics of 9791b227 from master with a
single pacman query instead of one per package.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Position the bar by dragging (or click-and-holding) empty bar space
toward a screen edge, with a ghost slab previewing the target edge.
With drag for position and double-click for transparency, the bar
config panel, its inline gear button, and the omarchy-launch-bar-settings
CLI are no longer needed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Copy URL extension was intermittently failing to copy anything, and
its notification looked oversized with no icon. Several distinct problems:
- The MV3 service worker was pinned to stale cached code. Chromium caches
the worker script for a --load-extension command-line extension and does
NOT re-register it when the file changes in place — not on restart, not on
a manifest version bump, not even after a clean shutdown. So updated code
never took effect: the old worker kept calling chrome.scripting.executeScript,
which throws once the scripting permission is gone, and the copy silently
failed. Renaming the worker to a versioned filename (background-2.js) is a
new script URL, which forces a fresh registration for everyone — new
installs and existing installs alike. Rename it again on any future worker
change (see the note at the top of background-2.js).
- Clipboard writes now go through an offscreen document (MV3's sanctioned
path) using a textarea + execCommand('copy'), replacing executeScript +
navigator.clipboard. This works on chrome:// pages and needs no scripting
permission. execCommand is used deliberately: navigator.clipboard.writeText
rejects in an unfocused offscreen document.
- Add a toolbar action (chrome.action.onClicked) so the extension is
clickable, not keyboard-only — it was greyed out in the extensions menu
with nothing to invoke.
- Slim the "URL copied" notification: lead the summary with a glyph so the
omarchy notification shell collapses it to a single-line toast with an
icon, instead of an oversized card with a blank icon slot.
- Guard the Quattro shortcut-repair migration: it edits Chromium Preferences
to move the Alt+Shift+L binding to the new extension id, but a running
browser rewrites Preferences on exit and reverts the edit. Prompt (via gum)
to close the browser first, only when a browser is running and there is
actually a stale binding to repair.
The omarchy-bar command had grown three overlapping ways to inspect the
bar (show/layout/list/options, plus selected/active/available/widgets
aliases) and mixed layout mutation in with bar-level settings. Untangle
it into two focused commands:
- omarchy-bar keeps only the bar-level settings that write shell.json:
use, reset, position, transparent, and settings. reset now delegates
to `use omarchy.bar` rather than duplicating the del(.bar.id) write.
- omarchy-bar-plugin owns all layout mutation: add, move, remove, set,
and replace, with the placement flags and jq resolve/anchor helpers.
`omarchy bar plugin ...` routes here via the dispatcher.
Drop the inspection commands entirely: the layout is visible on the bar,
the config is shell.json, and widget/option ids come from
`omarchy plugin list`. Nothing consumed the show output programmatically
except tests. This also removes omarchy-bar-position, whose jq write was
a duplicate of `omarchy bar position`.
Strip environment-invariant guards (require_command, require_omarchy_path)
that defended against jq or OMARCHY_PATH being absent — neither happens on
a real system. Keep the user-input validation (--section/--index) and the
atomic shell.json write.
Update callers (service install/remove, refresh-shell, plugin-clone,
plugin enable), keybindings, the menu, tests, and docs to the new split.
The weather widgets asked wttr.in to geolocate by IP, which lands on
whatever city the ISP registers its address block under -- Downey when
you're in Malibu. Now the location can be set explicitly:
* Click the location in the weather panel to search via open-meteo
geocoding, pick a suggestion (disambiguated by region), and it sticks.
The X next to the field returns to IP auto-detect, as does committing
an empty search.
* State lives in ~/.local/state/omarchy/settings/weather.json as
{name, latitude, longitude}, owned by the new omarchy-weather-location
command (bare call prints the current location, --set/--clear write).
The panel watches the file, so hand edits apply live.
* Stored coordinates make wttr.in and open-meteo exact. Open-meteo also
now supplies current conditions alongside the daily forecast it
already served, which fills the panel within a second of a location
change instead of waiting out wttr.in's multi-second responses; wttr
results still win once they land. Failed wttr fetches retry instead
of sitting stale until the next refresh cycle.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
9914513a unified internal monitor detection but left the test grepping
for the old jq expression. Since the suite runner stops on first
failure, every test file after monitor-recovery went silently unrun --
281 assertions were being skipped while the suite looked green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the three-layer process management (trap cleanup, PPID-polling
watchdog subshell, /proc-scanning reaper) with kernel-level lifetime
binding: each wl-paste watcher is spawned under setpriv --pdeathsig TERM,
so it dies with the shell no matter how the shell exits.
- Delete watch.sh: the shell now spawns both watchers directly as
declarative Process commands instead of a wrapper script with traps
and a 1s polling loop
- Delete init.sh: reaping stale watchers from a crashed pre-pdeathsig
shell is a single pkill at startup
- Collapse capture.sh's dual stream/snapshot modes: wl-paste forwards
arguments to its watch command, so the mime rides along as $1 instead
of an env var, letting both modes share one emit_image function
- Turn the six-branch image mime chain into a loop
Net: two fewer files, three fewer runtime processes, and the watch-mode
capture tests now exercise the same argument protocol the shell uses.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>