Commit Graph
5403 Commits
Author SHA1 Message Date
David Heinemeier Hansson 22791803ed Align vertical bar widgets to the icon grid 2026-07-17 16:03:49 -07:00
David Heinemeier Hansson 0c8c4ea26a Align bar icons on a shared baseline 2026-07-17 15:37:01 -07:00
David Heinemeier Hansson 6e3b69b8da Standardize bar icon geometry 2026-07-17 15:20:55 -07:00
David Heinemeier Hansson fe48e83222 Repair Tailscale authorization flow 2026-07-17 10:20:08 -07:00
David Heinemeier Hansson 16b5f2157f Preserve user state during theme setup 2026-07-17 07:59:20 -07:00
David Heinemeier Hansson 09aac40eae Gate first-run setup as one lifecycle 2026-07-17 07:59:16 -07:00
David Heinemeier Hansson 39756d485d Synchronize weather location updates 2026-07-16 21:54:57 -07:00
David Heinemeier Hansson e82df1d4d0 Track one-time setup with completion markers 2026-07-16 21:53:15 -07:00
David Heinemeier Hansson 7b824b6e1b Fix saving typed weather locations 2026-07-16 21:23:32 -07:00
David Heinemeier Hansson b79ae75833 Fix graceful window closing before reboot 2026-07-16 21:19:28 -07:00
David Heinemeier Hansson 93181b6a22 Restore service widgets with bar defaults 2026-07-16 21:15:00 -07:00
David Heinemeier Hansson af601381ca Ensure lock is setup on migration 2026-07-16 20:46:41 -07:00
David Heinemeier Hansson c58d00f203 Repair Copy URL shortcut during Quattro upgrade 2026-07-16 16:50:29 -07:00
David Heinemeier HanssonandClaude Fable 5 5044e711a0 Let the weather panel be pinned to a chosen location
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>
2026-07-16 14:46:56 -07:00
David Heinemeier HanssonandClaude Fable 5 95c1ff0901 Fix stale monitor assertion that silently halted the test suite
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>
2026-07-16 14:44:05 -07:00
David Heinemeier HanssonandClaude Opus 4.8 6f6c991936 Remove dead code from plugin scripts
canonical_widget_id was a pure pass-through, making its reserved-id
check a tautology; require_omarchy_path and choose_value were defined
but never called.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 08:03:01 -07:00
David Heinemeier Hansson ad8ab1a7fa Rename text capture command 2026-07-15 18:23:40 -07:00
David Heinemeier HanssonandClaude Fable 5 51bd33d7ab Keep tmux cursor colour on theme after apps reset it
Apps like nvim clear the per-pane cursor colour with OSC 112, which made
tmux reset the outer terminal's cursor. Terminals that can't reload their
config (foot) then restore the cursor colour from whatever theme was
active at launch, leaving a mix of old and new cursor colours across
panes. Set the global cursor-colour option as a fallback so cleared panes
land on the current theme instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:13:39 -07:00
David Heinemeier Hansson 38f516c430 I never use a dedicated web app for this
So let's just drop it
2026-07-15 17:57:24 -07:00
David Heinemeier Hansson 47f3074e4e Fix launcher application icon resolution 2026-07-15 17:45:27 -07:00
David Heinemeier Hansson 298e14071b Take a system snapshot before upgrading to quattro 2026-07-15 17:08:24 -07:00
David Heinemeier Hansson 2f7a07edbe Better wording for unlink as well 2026-07-15 15:28:09 -07:00
David Heinemeier Hansson dd00f20608 Offer the reboot, simplify wording 2026-07-15 15:25:44 -07:00
David Heinemeier Hansson aac579a2df Add rsyncing to remote host intended for easy forwarding of screenshots to remote AI runners 2026-07-15 10:54:30 -07:00
David Heinemeier Hansson 45a9d4ed1b We ride with danger or not at all 2026-07-14 17:23:01 -07:00
David Heinemeier HanssonandGitHub d25abba046 Merge pull request #6221 from kevinmcconnell/systray-action-fix
Fix bar plugin array guards
2026-07-14 11:05:22 -07:00
David Heinemeier HanssonandGitHub 07568e165a Merge pull request #6218 from kevinmcconnell/fix-transparent-bar-flicker
Prevent using an opaque surface for bar
2026-07-14 11:04:57 -07:00
Kevin McConnell d5492db404 Fix panel array guards
The `Bar` uses a `Repeater` when building out the models. This has the
effect of marshalling the configuration, and causing JSON arrays to
become sequence wrappers.

A couple of the plugins had been checking for the existence of array
values with `Array.isArray`, which fails for the sequence wrappers,
causing the values to be ignored. This breaks associated functionality
(the "hide" and "pin" actions in the systray had stopped working, as had
exit node selection in Tailscale).

Switching the guards to use `instanceof Array` works correctly for
sequence values (as well as arrays).
2026-07-14 15:36:43 +01:00
Kevin McConnell be595c72ad Prevent using an opaque surface for bar
The bar supports switching between transparent and opaque. That means we
can't use an opaque surface for it; if we did, it would be unable to
reliably render as transparent when needed.

This fixes a visual glitch where the background of a transparent bar
would flicker, particularly during mouse hover.
2026-07-14 10:00:19 +01:00
David Heinemeier Hansson d570d99e16 Turn off fade switching between window groups 2026-07-13 12:37:38 -07:00
David Heinemeier Hansson 935283c849 Simplify rendering
It's adding so little visual flair and is a source of GPU load
2026-07-13 10:11:32 -07:00
David Heinemeier Hansson cb8ab2d9f4 Properly render tray icons 2026-07-13 09:56:20 -07:00
David Heinemeier Hansson 17efd5e493 Ensure EDITOR is exported for non-uwsm envs too
Like SSH'ing into an Omarchy machine
2026-07-11 11:42:55 -07:00
David Heinemeier Hansson cc64c3e27c Add mup alias for skipping mise up delayed updates 2026-07-09 11:25:34 -07:00
David Heinemeier HanssonandClaude Fable 5 7ff91d9d5c Only carry over user-added theme backgrounds during the quattro upgrade
The trailing slash from the themes/*/ glob put a double slash in the
path comparison, so stock backgrounds never matched git ls-files output
and were all moved into ~/.config/omarchy/backgrounds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:16:16 -07:00
David Heinemeier HanssonandClaude Fable 5 4abd084f7f Don't glob dotfiles twice when building the live omarchy overlay
With dotglob set, * already matches dotfiles, so the extra dot patterns
made the second ln -s fail and silently skip the legacy hypr shim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:16:16 -07:00
David Heinemeier HanssonandClaude Fable 5 f1bc8dad08 Purge stale omarchy package cache before the first quattro transaction
Legacy repos cached omarchy packages under the same name and version as
quattro rebuilds with different bytes, so pacman aborted --noconfirm
transactions with checksum errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 18:16:16 -07:00
David Heinemeier Hansson aabae6fffe Group all the omarchy-bar bins together 2026-07-08 11:49:56 -07:00
David Heinemeier HanssonandClaude Fable 5 c4b1e33669 Route the weather toggle through the shell target too
Weather wraps its panel in a BarWidget that only exposed togglePanel(),
so it couldn't ride the new shell-routed hotkey path and was left on the
stale-prone per-plugin target. Expose open/close/opened on the wrapper
(open maps to the panel's hotkey path so the center hover reveal stays
suppressed) and switch omarchy-notification-weather to the new syntax.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:18:03 -07:00
David Heinemeier HanssonandClaude Fable 5 e1cdc9005e Route panel hotkeys through the shell IPC target so they survive reloads
Bar-widget panels (audio, bluetooth, network, power, monitor) used to be
toggled via their own per-plugin IpcHandler targets. Quickshell resolves
duplicate targets first-handler-wins, so after a plugin or bar reload the
stale handler of the destroyed widget instance kept claiming the target
and the hotkeys went dead.

The shell root's IpcHandler lives outside the reload cycle, so summon,
hide, and toggle now go through `omarchy-shell shell toggle <plugin>`
and the shell routes to the live widget instance via the bar's slot
registry. Panel plugins that are also panel/overlay/menu kinds keep
using the panel loader path. Failures to find a live widget are logged
so a widget missing from the bar layout stays diagnosable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:17:54 -07:00
David Heinemeier HanssonandClaude Fable 5 6bb3cb666b Rename debugModuleSlots to moduleSlots
The slot registry is about to become the routing table for panel
hotkeys, so it has outgrown its debug-only name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 09:17:37 -07:00
David Heinemeier Hansson af828481b9 Give it a little more time
Felt too abrupt at 3s
2026-07-04 12:08:34 -07:00
David Heinemeier Hansson 09a189e49f Set title from tmux so it's easier to use with multiple servers 2026-07-04 11:44:39 -07:00
David Heinemeier HanssonandClaude Fable 5 1e996609a0 Capture the entire screen with Return during a region pick
A previous submap attempt was brittle because the script owned the
keyboard state: if it died between enter and exit, the submap stuck.
This version lets the compositor own both edges. The Lua config binds
plain Return when a layer surface with slurp's "selection" namespace
opens and unbinds it when the last one closes, so the bind exists
exactly while a pick is on screen. slurp dying for any reason (cancel,
crash, pkill, SIGKILL of the picker) fires layer.closed and the bind
evaporates — there is no code path where it leaks.

Return invokes omarchy-capture-region --take-fullscreen, which flags a
marker in XDG_RUNTIME_DIR and dismisses slurp; the picker treats an
empty slurp result with a fresh marker as the focused monitor, reusing
the existing fullscreen path. Since monitor focus follows the cursor,
that is the monitor under the slurp crosshair. The recording flow gets
monitor:NAME from the existing match, so Return during a recording
pick starts a native full-monitor capture.

The signal mode no-ops unless slurp is actually running, and both the
signal protocol and the layer-scoped bind lifecycle are verified live:
bind present only while slurp is open, real picks resolved by the
signal on both the screenshot and recording paths, no leftover binds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 10:13:19 -07:00
David Heinemeier HanssonandClaude Fable 5 b72aa8f65e Rename region picker to omarchy-capture-region
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 09:30:41 -07:00
David Heinemeier HanssonandClaude Fable 5 362d97c151 Share one region picker between screenshot and recording
Both capture scripts carried the same pipeline: workspace rectangles
from hyprctl, a hyprpicker freeze, slurp, and the bare-click snap loop.
The copies had already diverged once (rotated-display handling), so the
pipeline now lives in one hidden helper, omarchy-capture-region-pick,
which prints the picked geometry in slurp format.

The two callers differ only in what they layer on top. The screenshot
needs the freeze to outlive the pick so grim captures frozen content:
--keep-freeze leaves hyprpicker running and prints its PID first, with
the caller owning the kill. The recording prefers native full-monitor
capture: --match-monitor prints monitor:NAME when the geometry exactly
matches a display.

One deliberate fix along the way: the screenshot snap regex rejected
negative coordinates, so bare clicks on monitors positioned left of or
above the origin never snapped. The helper uses the recording variant,
which handles them.

Verified with an 11-case shim harness (snap precedence, rotated-monitor
match, freeze ownership, cancellation, negative coordinates) and the
live end-to-end screenshot sanity test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 09:26:46 -07:00
David Heinemeier HanssonandClaude Fable 5 3bd6e72211 Share one theme color resolver across consumers
Five scripts each hand-rolled colors.toml parsing plus their own
alias/fallback cascade, and the tables had drifted: theme-osc grew a
divergent color8/color9 chain, tmux and gnome carried private mode
detection, and the preview tool duplicated the lot. The differences
never mattered for shipped themes but were a standing bug factory for
sparse user themes.

omarchy-theme-color is now the single resolver. Its cascade is a
verbatim port of the canonical theme-set-templates logic (semantic
keys, legacy colorN aliases, derived shades, selection/cursor
derivation, mode precedence), exposed as --all, --raw, or single-key
lookup with fallback.

Generated output is byte-identical across all 21 shipped themes on
every surface: 17 template files, OSC byte stream, tmux and gsettings
command logs, and previews. Sparse legacy themes now resolve the same
palette everywhere instead of five slightly different ones.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 09:06:31 -07:00
David Heinemeier HanssonandClaude Fable 5 03f7420d72 Pass empty placement explicitly in bar replace
cmd_replace fed $PLACEMENT_FROM_SECTION/$PLACEMENT_FROM_INDEX to jq
without ever calling parse_placement, so they were always empty
strings that implied flag support which does not exist. Pass literal
empties with a comment stating replace resolves by widget id only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:14:33 -07:00
David Heinemeier HanssonandClaude Fable 5 54539b4a83 Handle rotated monitors in the recording picker
The screenshot picker swaps monitor dimensions for transform 1/3
displays; the recording copy had drifted and did not, so portrait
monitors got landscape rectangles in the picker. The full-monitor
match had the same blind spot, silently downgrading rotated-monitor
selections to region capture instead of native -w capture.

Both now share the screenshot script's format_geo jq helper, which
also lets the monitor match compare one geometry string instead of
four fields.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:14:33 -07:00
David Heinemeier HanssonandClaude Fable 5 9914513a31 Unify internal monitor detection across scripts
Four scripts matched internal panels with contains("eDP") while
omarchy-monitor-state used test("^(eDP|LVDS|DSI)-"), so laptops with
LVDS or DSI panels were internal to monitor-state but invisible to the
clamshell, mirror, and external-active logic. All five sites now share
the inclusive anchored pattern.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:14:33 -07:00