Commit Graph
1134 Commits
Author SHA1 Message Date
David Heinemeier Hansson f22e8cd353 Merge remote-tracking branch 'origin/quattro' into fix-snapshot-locate-and-timeline-leak
# Conflicts:
#	docs/file-layout.md
2026-07-26 19:14:09 -07:00
David Heinemeier HanssonandClaude Opus 5 a6a13cf3e6 Replace the in-flight updatedb and read PRUNEPATHS out of any quoting
The machines this targets are the ones with an updatedb already grinding
through every snapshot, and `systemctl start` on an active unit is a
no-op. updatedb reads /etc/updatedb.conf once at startup, so a run that
began before the rewrite keeps burning CPU on the old config until it
finishes. Restart the service instead: it's Type=oneshot and plocate
builds into a temp db, so nothing is lost by replacing the run.

Quotes are optional in updatedb.conf, so parse the existing paths out of
whatever quoting the file uses and write the setting back in one
canonical form. `PRUNEPATHS=/tmp` previously fell through to the append
branch and got a second PRUNEPATHS line, which drops /tmp from the
pruned set. Comparing whole paths rather than substrings also keeps a
config that already prunes something like /var/lib/machines/.snapshots
from being mistaken for one that prunes /.snapshots.

Prefer $OMARCHY_PATH over the packaged copy when locating the config
script, per docs/migrations.md, so the migration test exercises the
checked-out script rather than whatever release is installed. Skip when
neither exists: omarchy-migrate runs under set -e, so a missing script
would take down every migration queued behind it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 19:00:02 -07:00
David Heinemeier HanssonandClaude Opus 5 425c3ff84d Only check for pending migrations at login
omarchy-update-user-notify.path watched /usr/share/omarchy/migrations, but
pacman writes that directory during every update, including the blessed
omarchy update, which runs omarchy-migrate a step later. The watcher fired a
critical notification for the migrations the update was already applying in
the visible terminal. A watcher cannot tell that apart from a bypassed
pacman -Syu, so the only trigger that never collides with a running update is
a once-per-login check.

The service that already ran at graphical-session.target is now the whole
mechanism, renamed after the command it runs. That is also all the second-user
case needs: markers are per-user, so anyone who did not run the update finds
them missing at their next login.

Login timing means the toast can be sent before the shell has claimed
org.freedesktop.Notifications, so the notifier waits for a live server first.
The wait is omarchy-first-run's, lifted into omarchy-notification-wait rather
than duplicated.

The package keeps omarchy-update-user-notify.service as a symlink onto the new
unit. Existing users hold an absolute wants symlink to the old path, and the
migration that repoints it only runs for users who run an update, which is the
opposite of who the notifier is for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 14:53:29 -07:00
David Heinemeier Hansson a8977c4433 Only show linux-ptl kernel when that's installed so we don't end up with two options on XPS 2026-07-26 10:53:18 -07:00
David Heinemeier HanssonandClaude Opus 5 1756864129 Swap the Panther Lake kernel in before the camera DKMS modules
A fresh install on a Dell XPS 14 spent 73s in "Configuring system", and two
silent gaps in the install log account for 66s of it. Both are the same
redundant work.

hardware/all.sh ran ipu7-camera.sh before ptl-kernel.sh. intel-ipu7-camera
pulls in ipu7-drivers, vision-drivers and v4l2loopback, so DKMS compiled all
three against the stock linux kernel and built a UKI for it. ptl-kernel.sh
then installed linux-ptl, which recompiled the same three modules against the
new kernel, and its pacman -Rdd of linux followed with three dkms removes and
yet another UKI rebuild. The log shows four UKI builds where one would do, and
everything the first script produced was deleted 42 seconds after it was made.

Running the kernel swap first means the DKMS modules are only ever built
against the kernel the machine actually keeps, which returns roughly 25s.

ptl-kernel.sh still installs linux-ptl before removing linux, so one redundant
UKI build for the stock kernel remains. Removing first would save it but would
leave the machine with no kernel at all if the linux-ptl install failed, so the
safe order stays.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017q97Rsk8KwgaPUVq5ArLgM
2026-07-25 13:37:07 -07:00
David Heinemeier Hansson be781574d1 Let the invitation terminals actually open
Clicking the Voxtype or fingerprint invitation did nothing. The launcher
execs setsid, which forks because the transient unit's main process is
already a process group leader, so the unit exits within milliseconds and
systemd's default control-group kill took the still-starting terminal down
with it. Run those units with KillMode=process instead.

The invitation tests had also drifted from the two-unit design and were
failing; teach the systemd-run mock to run the command it is given.
2026-07-24 18:57:51 -07:00
David Heinemeier Hansson 0b564255ea Stack the Wi-Fi toast above the update toast on first run
Both notifications are sent from background subshells, so whichever
notify-send registered first won the bottom slot. Give the update toast a
tick to register so Wi-Fi lands newest and stacks on top.
2026-07-24 18:52:26 -07:00
David Heinemeier HanssonandClaude Opus 5 aa9f0c54c5 Add per-laptop speaker tunings, starting with the XPS 14
Laptop speakers ship voiced by the vendor's Windows DSP layer, which Linux does
not get. A tuning restores that as a PipeWire filter-chain in front of the
internal speaker sink, matched to the machine by DMI string and expected sink.

Adding a laptop is a directory under default/audio/tunings with two files and no
new code: matching is data. The XPS 14 DA14260 tuning included here was derived by
measuring the xps-audio-linux EasyEffects profile (MIT) and fitting a biquad chain
to it, so no impulse response or other upstream asset is redistributed. It measures
1.24 dB RMS against that reference, and matches its dynamic range within 0.1 LU --
the reference's multiband compressor turned out to contribute nothing, so a linear
chain replaces it. Bass Q is capped deliberately: a closer magnitude fit swung
group delay 31 ms across 63-80 Hz, which smears bass transients.

The graph runs as its own PipeWire client under its own config name rather than
loading into the audio daemon. The daemon only reads its config at startup, so a
daemon-loaded tuning could only be switched by restarting PipeWire -- which drops
every PulseAudio client's connection, and applications that do not reconnect
(Spotify) then have to be restarted by hand. Hosting it separately also contains
failure, since a malformed tuning breaks only that service.

Three things about the surrounding audio graph needed fixing for this to behave:

- Volume must live downstream of the tuning. omarchy-audio-output-sink is now the
  single definition of which sink an output's volume really uses, shared by the
  volume keys, the output switcher's OSD and the audio panel, so they cannot
  disagree. It resolves the current default output, which keeps it correct when
  headphones are selected while a tuning exists.
- The tuning's own output is a movable sink input, so rerouting "all streams" to a
  newly selected output would drag the processing onto headphones, or into the
  tuning's own sink, which is a cycle. It is pinned, and stream moves are limited
  to streams carrying an application.name.
- The physical sink a tuning fronts is not independently selectable, since picking
  it would only bypass the tuning, so it is kept out of the output list.

Applying happens at first-run, not finalize-user, because finalize-user also runs
in the ISO chroot where there is no audio server and nothing would retry.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 18:25:02 -07:00
David Heinemeier HanssonandClaude Opus 4.8 555cb4db75 Stop install invitations from re-showing after they run
Voxtype/fingerprint invitations run as a transient
omarchy-*-invitation.service that shows a critical toast and waits for a
click. On click the service execs the install terminal, so the service
stays active for the whole life of that terminal.

The installer ends with omarchy-restart-shell, which re-triggers any
still-running omarchy-*-invitation.service on the assumption that a
still-running unit is an unanswered toast wiped by the shell restart. But
an answered invitation is still running only because it is the parent of
the very install terminal that triggered the restart, so it gets falsely
re-fired and the invitation toast pops a second time right after the
install finishes.

Launch the installer in its own transient unit so the invitation service
exits immediately after the click. Genuinely unanswered invitations still
block in notify-send and are still recovered by restart-shell; answered
ones are gone and no longer match the re-show glob.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WHPDqx5hwLTwq27f7KpM9d
2026-07-24 16:36:50 -07:00
David Heinemeier HanssonandClaude Opus 5 fe036a82fa Give every install group an all.sh driver
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 12:27:01 -07:00
David Heinemeier HanssonandClaude Opus 5 a2ec713603 Collapse the duplicated run_logged invocation branches
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 12:23:23 -07:00
David Heinemeier HanssonandClaude Fable 5 00eae9a5ef Invite fingerprint setup after the first system update
The setup installs packages (libfprint-git, fprintd, usbutils), which
isn't reliable on a fresh install before the databases have been
synced. Defer the invitation with a post-update hook, like Voxtype.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 19:25:06 -07:00
David Heinemeier Hansson b6e75d5e48 Language improvements 2026-07-23 14:08:08 -07:00
David Heinemeier HanssonandClaude Opus 4.8 e2bf0daaa8 Invite fingerprint setup on first run when a reader is present
Add a first-run notification, alongside the keybindings/Wi-Fi toasts, that
invites anyone with a fingerprint sensor to enable it. Clicking launches
omarchy-setup-security-fingerprint in a floating terminal.

Detection lives in a new omarchy-hw-fingerprint helper that reads sysfs
(device product descriptor plus a fingerprint-vendor allowlist), so it
works before fprintd/usbutils are installed and without nagging machines
that have no reader. The setup script reuses the same helper as an early
gate, bailing before installing any packages when no reader is found
(replacing the old post-install fprintd-list probe).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 14:05:31 -07:00
Martin Bastien 8ef4eb24a2 Keep Btrfs snapshots out of the locate index and put /home in it
The stock Arch updatedb.conf interacts badly with Omarchy's Btrfs
layout in both directions:

- Snapper snapshots under /.snapshots are nested subvolumes reached by
  plain directory traversal, so updatedb indexes the entire system once
  per snapshot. On machines that accumulated snapshots this means
  multi-hour updatedb runs at full CPU, gigabytes of RAM, and a
  multi-gigabyte plocate.db (observed: 18 GB db, 7.5 h runs at 96% CPU
  with 592 snapshots; 43 MB and ~1 min after the fix).
- PRUNE_BIND_MOUNTS="yes" treats Btrfs subvolume mounts like /home as
  bind mounts, so locate finds nothing in home directories at all.

Configure updatedb.conf at install time and migrate existing installs,
then rebuild the index in the background. Both settings are matched
tolerantly and appended when absent, so a hand-edited updatedb.conf is
fixed rather than silently skipped.
2026-07-23 09:10:16 -04:00
David Heinemeier Hansson 83d20b07d1 Use current .NET runtime package 2026-07-22 17:31:14 -07:00
David Heinemeier HanssonandClaude Fable 5 21eacb324a Ship quickshell as quickshell-git for synchronous kill
quickshell 0.3.0's qs kill returns before the instance exits, forcing
restart tooling to babysit pids. Upstream fixed kill to block until the
process is gone, but only on master, so the Omarchy repo now carries
quickshell-git pinned past that fix. New installs get it from the base
packages; existing installs migrate with a single --ask 4 transaction so
the conflicting quickshell package is replaced in place, then restart
the shell after the update to pick up the new binary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 15:27:12 -07:00
David Heinemeier Hansson 51d6d3c291 Fix Voxtype invitation action 2026-07-21 11:22:51 -07:00
David Heinemeier HanssonandClaude Opus 4.8 0f691d60fb Scale the Dell XPS 13 default via display text size
Use omarchy-display-text-size 11 instead of a lone GTK text-scaling-factor,
so the XPS 13 nudge moves shell, GTK, and terminal text together.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 18:08:17 -07:00
David Heinemeier HanssonandClaude Fable 5 5232505c12 Don't block the desktop on network-online at boot
graphical.target was gated on network-online.target: cups-browsed orders
itself After=network-online.target and sits in multi-user.target, so the
session waited for NetworkManager-wait-online (DHCP/Wi-Fi association)
before coming up. On the bench VM that was ~140ms, but it's the classic
multi-second boot stall on real Wi-Fi.

Mask NetworkManager-wait-online.service so network-online.target is
reached immediately and nothing in the boot waits for connectivity;
NetworkManager still comes up and cups-browsed browses once the link is
live. Mirrors the existing systemd-networkd-wait-online mask. Enabled at
install (enable-services.sh) and masked on existing installs via
migration.

Verified on a fresh boot: the graphical.target critical chain no longer
passes through network-online.target / NetworkManager-wait-online.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 10:34:26 -07:00
David Heinemeier HanssonandClaude Fable 5 b87de89372 Stop the migration notifier from busy-looping the session
omarchy-update-user-notify.path used PathExistsGlob= on the packaged
migrations directory. That directive is level-triggered: systemd re-checks
it every time the triggered unit deactivates and fires again while the glob
still matches. Since applied migrations stay on disk forever (state lives in
~/.local/state/omarchy/migrations), the glob always matches, so the oneshot
notifier re-triggered itself in a tight loop (~26-66 starts/sec) — burning
about a core and flooding the journal for the whole session.

The loop existed since the unit was introduced, but the default start-rate
limit killed it after 5 iterations, taking the .path unit down with
'unit-start-limit-hit'. That symptom was reported as #6174 and fixed
yesterday by setting StartLimitIntervalSec=0 — which removed the only brake
and turned the capped hiccup into an unbounded busy-loop.

Fix the actual cause instead:

* Drop PathExistsGlob= from the .path unit, keeping the edge-triggered
  PathModified= watch for updates that land mid-session.
* Revert the StartLimitIntervalSec=0 override; with the level trigger gone
  there is no self-re-fire to trip the limit, and the default limit is a
  useful backstop again.
* Preserve the once-per-login pending check the glob used to provide by
  giving the service its own WantedBy=graphical-session.target, enabled at
  first-run alongside the other user units.
* Add a migration that daemon-reloads, revives a rate-limit-killed .path,
  restarts the watcher, and enables the login-time notifier on existing
  installs.

Verified with transient path/service units: the old config runs the service
200 times in 3 seconds; the new config runs it zero times while idle and
exactly once when a new migration file lands.

Thanks to @HANCORE-Linux for finding and diagnosing the problem.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 21:49:41 -07:00
David Heinemeier HanssonandClaude Fable 5 d211de2ffc Match Wi-Fi first-run notification format to the other invitations
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 21:17:04 -07:00
Stephen TaylorandDavid Heinemeier Hansson 9030ba870c Force software cursors on nouveau
Adapt the fix from PR #6161 to Quattro's per-user hardware setup and add coverage for detection, idempotency, and proprietary-driver handling.
2026-07-18 21:49:47 -07:00
David Heinemeier HanssonandClaude Fable 5 46df0cf495 Nudge XPS 13 text scaling down just ever so slightly
The 2560x1600 panel on the 2026 XPS 13 (DX13260) renders the default
scaling a touch large. Ports f1fa7f69 from master.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 12:31:25 -07:00
David Heinemeier HanssonandClaude Fable 5 804d138909 Widen sof-firmware install to all Intel SOF audio platforms
The sof-audio-pci-intel-* driver family needs sof-firmware to boot the
DSP, but mainline linux only optdeps it, so affected installs came up
with a Dummy Output sink only. Replace the Panther Lake check with
omarchy-hw-intel-sof, which detects any Intel PCI audio controller.

Ports ffa81021 from master, which adapts basecamp/omarchy#6200.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 12:31:25 -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 e82df1d4d0 Track one-time setup with completion markers 2026-07-16 21:53:15 -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 Hansson 4772f01148 Was used by walker but no longer used 2026-06-22 21:01:34 +02:00
David Heinemeier Hansson 383423036f Add omacut as a default package 2026-06-22 17:39:53 +02:00
David Heinemeier Hansson 95888e69ff Replace Typora with Omawrite 2026-06-22 17:38:50 +02:00
Ryan Hughes c048b2c745 Normalize Snapper snapshot setup 2026-06-21 02:25:42 -04:00
Ryan Hughes 34ddf5d54e Fix NetworkManager transition during upgrade 2026-06-21 02:25:42 -04:00
Ryan Hughes 2a7602a084 Complete upgrade-to-4 update flow 2026-06-15 11:27:54 -04:00
Ryan Hughes 4bfa5a6949 Switch default editor to tensaku so we can move things 2026-06-12 22:27:20 -04:00
Ryan Hughes 0f5e81143e Move current theme state to local state 2026-06-09 19:48:37 -04:00
David Heinemeier Hansson 38bb61b685 Overly defensive 2026-06-08 17:48:09 +02:00
David Heinemeier Hansson 8807a9c889 Merge branch 'dev' into quattro 2026-06-08 16:36:51 +02:00
Carmine PaolinoandGitHub 9cf1852525 Use dua for disk usage (#6052) 2026-06-08 16:36:05 +02:00
Ryan Hughes d2c1544d78 Fix sleep lock service during Omarchy 4 upgrade 2026-06-06 19:31:51 -04:00
Ryan Hughes ddd7e058a2 Auto-mount removable drives by default with udiskie 2026-06-04 18:38:25 -04:00
Ryan Hughes 0804962619 Improve update and migration flow 2026-06-04 18:38:25 -04:00
Ryan Hughes 4e10d41f0e Start user units immediately in first-run, not just enable
systemctl --user enable only writes the .wants symlinks; the services
don't actually run until next login. Switching to --now enables AND
starts them, so the first session has bt-agent (bluetooth pairing) and
omarchy-sleep-lock active immediately rather than waiting a reboot.

omarchy-recover-internal-monitor is Type=oneshot with a
ConditionPathExists guard, so --now is harmless for it (it'll skip if
the toggle isn't set).
2026-06-04 18:38:25 -04:00
Ryan Hughes babfafa5e9 Split user defaults into skel seed, finalize, and resync
Reorganizes Omarchy 4 around three layers for populating $HOME:

  Seed:     omarchy-settings ships defaults to /etc/skel; useradd -m
            copies them on user creation
  Finalize: omarchy-finalize-user (renamed from omarchy-setup-user)
            handles only the runtime tweaks /etc/skel can't do — skill
            symlinks, xdg-user-dirs, default browser/mailto, vconsole→hypr
            keyboard sync, and install/user/all.sh
  Resync:   omarchy-reinstall-configs is the explicit, destructive
            resync of /etc/skel into an existing user's $HOME

Package-owned files move out of config/ into default/, where the
omarchy-settings PKGBUILD installs them to real system paths:

  config/environment.d/fcitx.conf            -> /usr/lib/environment.d/
  config/fontconfig/fonts.conf               -> /usr/share/fontconfig/conf.avail/
  config/mimeapps.list                       -> /usr/share/applications/
  config/omarchy.ttf                         -> /usr/share/fonts/omarchy/
  config/systemd/user/*.service              -> /usr/lib/systemd/user/
  config/uwsm/default                        -> /usr/share/omarchy/default/uwsm/
  config/uwsm/env                            -> /usr/share/uwsm/env.d/10-omarchy
  config/xdg-terminals.list                  -> /usr/share/xdg-terminal-exec/

omarchy-upgrade-to-4 grows a 'retire' action (renamed from 'move' to
clarify nothing is copied — the system path is owned by the new package
once the user's hash-matched ~/.config copy is removed). Mismatched
copies are kept as backups so user overrides survive the upgrade.

Other simplifications:

  - Single env bootstrap at default/bash/env-bootstrap sourced by
    /etc/profile.d/omarchy.sh, /etc/skel/.bashrc,
    /usr/share/uwsm/env.d/10-omarchy, and default/bash/envs. PATH
    prepend only in dev-link mode (production uses /usr/bin/omarchy-*).
  - omarchy-refresh-config reads from /etc/skel/.config so refresh
    means 'snap to skel'.
  - omarchy-reinstall-configs collapses to 'cp -af /etc/skel/. ~/'
    plus limine/plymouth/nvim refresh.
  - omarchy-font-set uses awk against our own 30-omarchy.conf instead
    of xmlstarlet; xmlstarlet dropped from omarchy-base.packages.
  - Defer user systemd enables (bt-agent, sleep-lock,
    recover-internal-monitor) to first-run via
    install/user/first-run/enable-user-units.sh; delete
    omarchy-user-systemctl-enable and the per-hardware install
    scripts that called it.
  - Wireplumber bluetooth-a2dp-autoconnect.conf moves to config/ so
    /etc/skel ships it; install/user/hardware/bluetooth.sh deleted.
  - Default terminal switched to foot.desktop.
  - docs/file-layout.md documents the three-layer model and the
    build-time repo→path map.
2026-06-04 18:38:25 -04:00
Ryan Hughes 06db866467 Prepare installer for ISO-owned finalization 2026-06-04 18:38:25 -04:00
Ryan Hughes 75cb4f7195 Make setup ISO-only
Remove legacy online installer entrypoints, collapse migrations for 4.0, and move setup responsibilities into target-side system, hardware, and user commands.
2026-06-04 18:37:32 -04:00
Ryan Hughes b45e8464ef Move NVIDIA env setup to Hyprland Lua
Evaluate NVIDIA session env vars from default/hypr/nvidia.lua during Hyprland startup instead of appending them to each user's envs.lua during setup. This removes the per-user NVIDIA setup script execution while preserving the GSP/non-GSP detection.
2026-06-04 18:35:01 -04:00
Ryan Hughes 27f6d9d364 migrations: keep system helpers sudo-compatible 2026-06-04 18:35:01 -04:00
Ryan Hughes bf14f69017 installer: require target user for system finalizer 2026-06-04 18:35:01 -04:00