Commit Graph
6457 Commits
Author SHA1 Message Date
Ryan Hughes ff85faf8dd Make linux-omarchy the default kernel except on T2 Macs 2026-09-14 16:32:09 -04:00
Ryan Hughes b679363bed Merge pull request #11729 from omacom/fix/omarchy-ptl-kernel-migration
Migrate Panther Lake systems to the Omarchy PTL kernel
2026-09-13 11:51:18 -07:00
Ryan Hughes 8a972da975 Migrate Panther Lake systems to the Omarchy PTL kernel 2026-09-13 14:43:47 -04:00
David Heinemeier Hansson 8247eb36b7 Merge pull request #11637 from omacom/fix-powerprofile-poll-coredumps
Poll the active power profile over D-Bus instead of powerprofilesctl
2026-09-13 18:06:00 +02:00
David Heinemeier Hansson 5e261369bc Merge pull request #11712 from omacom/remove-codeowners
Remove CODEOWNERS
2026-09-13 17:58:56 +02:00
David Heinemeier HanssonandClaude Fable 5.1 8369601f26 Remove CODEOWNERS
No branch on the repo is protected and there are no rulesets, so the
file never enforced owner review. Its only effect was auto-requesting a
review from the other owner on every PR, which nobody acted on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 17:58:17 +02:00
David Heinemeier Hansson a2629d831a Merge pull request #11707 from omacom/fix-basecamp-github-urls
Point GitHub URLs at omacom/omarchy instead of basecamp/omarchy
2026-09-13 17:27:15 +02:00
David Heinemeier Hansson f8ceedcb50 Merge pull request #11703 from omacom/add-cloudflare-cli
Add Cloudflare CLI lazy wrapper
2026-09-13 17:23:04 +02:00
David Heinemeier HanssonandClaude Fable 5.1 d78ea9e158 Point GitHub URLs at omacom/omarchy instead of basecamp/omarchy
The repo moved to the omacom org. GitHub redirects the old URLs, but
`omarchy channel set dev` was still cloning from basecamp/omarchy, which
left every dev checkout with a stale origin remote that confuses gh
(pr create fails with "No commits between omacom:quattro and
basecamp:<branch>"). Update the clone URL, the quattro upgrade tarball,
the update-confirm release link, the systemd Documentation link, and
the manual.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LSFKDatumRZHB8zqk5CP5C
2026-09-13 17:20:29 +02:00
David Heinemeier Hansson 694e7b43a8 Merge pull request #11704 from omacom/fix-1password-window-class
Match 1Password's new window class so it floats again
2026-09-13 17:19:02 +02:00
David Heinemeier HanssonandClaude Fable 5.1 9ca462b153 Match 1Password's new window class so it floats again
1Password 8.12 changed its app id from "1Password" to
"com.onepassword.OnePassword" (its .desktop file now declares that as
StartupWMClass). Our window rule only matched the old name, so the main
window came up tiled and lost the no_screen_share protection.

Match both forms so older installs keep working.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LSFKDatumRZHB8zqk5CP5C
2026-09-13 17:05:40 +02:00
David Heinemeier Hansson a389bd1852 Add Cloudflare CLI lazy wrapper 2026-09-13 16:59:33 +02:00
David Heinemeier Hansson 6a89a39967 Merge pull request #11653 from omacom/io-scheduler-kyber
Use the kyber I/O scheduler on real disks
2026-09-13 16:45:15 +02:00
David Heinemeier Hansson cf17182bf5 Merge pull request #11698 from antonkesy/quattro
Fix typo in manual
2026-09-13 16:44:42 +02:00
Anton Kesy 69c67c63d6 Fix typo in manual 2026-09-13 16:28:44 +02:00
David Heinemeier Hansson 692c02cad5 Merge pull request #9140 from ogarza/center-qconsole
Center the Quake console in a 2:1 panel instead of spanning the screen.
2026-09-13 12:38:41 +02:00
David Heinemeier HanssonandClaude Opus 5 d377569edb Count only tiled windows and refit when apps move or float
A floating window on the console is not laid out by the gaps, so it no
longer stretches the panel to full width. Moving an app onto or off the
scratchpad and toggling floating now refit too, via
window.move_to_workspace and window.update_rules; both were measured on
Hyprland 0.56.2 to carry the settled count.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012UyVoFTM98Tduoxg7qZax7
2026-09-13 12:37:08 +02:00
David Heinemeier HanssonandClaude Fable 5.1 795ac57a6c Match only whole disks in the kyber udev rule
udev patterns are shell globs, so nvme[0-9]*n[0-9]* also matched every
partition. Partitions have no queue/scheduler, and udev logged a "Could not
chase sysfs attribute" for each one at boot. Restrict the match to
SUBSYSTEM block with DEVTYPE disk, which also keeps mmcblk boot areas and
NVMe multipath nodes out.

Reword the comment: kyber targets a read latency rather than bounding it,
and the kernel's default choice depends on the device rather than being a
fixed NVMe versus everything-else split.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 12:09:50 +02:00
David Heinemeier HanssonandClaude Fable 5.1 dae1f4bf0e Use the kyber I/O scheduler on real disks
The kernel leaves NVMe on none and everything else on mq-deadline. Neither
bounds latency once the device queue fills, so a large build, copy, or
package upgrade can make the desktop sluggish while reads wait behind a
wall of writes.

Kyber keeps separate read and sync-write queues and throttles the depth it
submits to hit a 2ms read target, which keeps interactive reads flowing
under heavy writes at negligible CPU cost. The trade is a small ceiling on
peak throughput on very fast devices, which matters for a storage server
chasing IOPS but not for a desktop.

Ships as a package-owned udev rule in /etc so it applies at boot and on
hot-plug. Existing installs pick it up at the next boot. zram is left alone
since it has nothing to schedule.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 11:53:27 +02:00
David Heinemeier Hansson 93d9d0c859 Merge pull request #11651 from omacom/shield-pacman-from-session-teardown
Shield pacman transactions from desktop session teardown
2026-09-13 02:17:24 -07:00
David Heinemeier HanssonandClaude Fable 5 83c6dd230c Keep the conflict tests inside their fixture despite the scope wrapper
The update conflict tests stub sudo and pacman, but omarchy-update-pacman
now puts systemd-run between them, so on a systemd-booted host the tests
would reach for the real system manager. Stub systemd-run to drop the
wrapper's options and run the command, and cover the helper's own
invocation composition in a new test.

Raised by codex review.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015zcqENR1UbhuwC1v5u3Wop
2026-09-13 10:35:32 +02:00
David Heinemeier HanssonandClaude Fable 5 24841ac5d2 Tell how to resume a channel switch that failed partway
omarchy-channel-set runs under set -e, so a failure after it has begun
mutating the system (dev link, pacman channel, packages) died silently
with the switch half-applied. Trap ERR once the mutation phase starts
and say how to pick the switch back up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-13 10:21:46 +02:00
David Heinemeier HanssonandClaude Fable 5 bc0753dfcb Show a failure state when a presented command exits non-zero
The floating-terminal presentation wrapper showed the green "Done!"
prompt for every exit code except Ctrl-C, so a failed update or channel
switch closed looking like a success. Pass the command's exit code
through to omarchy-show-done and render a red "Failed (exit code N)!"
prompt when it is non-zero. The pkg install/remove pickers get the same
treatment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-13 10:21:46 +02:00
David Heinemeier HanssonandClaude Fable 5 f5194e3ff5 Shield Omarchy pacman transactions from desktop session teardown
Upgrading systemd runs its post_upgrade scriptlet mid-transaction, which
reexecs both the system manager and every user manager. When pacman runs
inside a user-session scope (the floating update terminal), that reexec
can SIGKILL it and abandon the transaction halfway, with packages
upgraded but none of the post-transaction hooks run.

Route every Omarchy-owned system mutation through a new hidden
omarchy-update-pacman helper that registers the transaction as a PID 1
scope via systemd-run, keeping it out of the user manager's cgroups.
System scopes survive the system manager's own reexec, and as a bonus the
transaction now also survives its terminal window closing. On unbooted
systems (the installer chroot) the helper runs pacman directly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-13 10:21:38 +02:00
David Heinemeier HanssonandClaude Fable 5.1 1b001a69d3 Re-center the Plymouth prompt when a display appears late (#11641)
The theme laid out the logo, password entry and progress bar once, when
the script first ran. Plymouth sizes its window to the largest display
present, so a monitor that comes up after plymouthd starts (a Thunderbolt
display whose DisplayPort tunnel is established about a second after the
kernel's display driver loads, a dock, an MST hub) got the prompt drawn at
the internal panel's coordinates: off-center on the external display and
partly off-screen on the panel. With the lid closed the passphrase box was
effectively invisible.

Move the layout into a function and re-run it from the refresh callback
whenever Window.GetWidth/GetHeight change, which is how Plymouth's script
plugin exposes a display being added or removed. Existing bullets are
repositioned too.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-13 00:56:44 -07:00
David Heinemeier HanssonandClaude Fable 5.1 55799c4ab0 Poll the active power profile over D-Bus instead of powerprofilesctl
The battery service ran `powerprofilesctl get` every two seconds to keep the
active profile visible to the wallpaper and lock services. That command is a
PyGObject script, so the shell spawned a Python interpreter for it tens of
thousands of times a day. Roughly once a day one of those exits into a CPython
3.14 finalization race (python/cpython#124619): the GLib D-Bus worker thread
calls PyGILState_Ensure after the interpreter is torn down and the process
dies with SIGSEGV, leaving a core dump and a crash notification behind.

Read the ActiveProfile property straight from power-profiles-daemon with
busctl, the same way omarchy-powerprofiles-set already reads UPower. The
output is JSON, so an empty or malformed reply when the daemon is not running
still reads as no active profile, matching the previous behaviour.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011gbfh4Mi9dK6SAd1P2xMTi
2026-09-13 08:56:39 +02:00
David Heinemeier HanssonandClaude Fable 5.1 31bd80daa4 Keep the KEF LSX II LT USB sink from suspending (#11318)
The speaker's USB firmware stops answering control requests when the host
stops the audio stream after WirePlumber's 5 s idle suspend. The kernel
then logs usb_set_interface failed (-110), clock source 1 is not valid,
and cannot set freq 48000 err -110; PipeWire fails to start the sink and
only a replug recovers it. On one machine this happened on six days over
three weeks, up to hundreds of timeouts a day.

A WirePlumber rule sets session.suspend-timeout-seconds = 0 for the KEF
node only, so the stream is never stopped and the trigger never fires.
Other sinks keep the default. The migration seeds the file for existing
installs and restarts WirePlumber if it is running, since conf.d is only
read at startup.

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 21:51:13 +02:00
Ryan Hughes b5589faaf8 Merge pull request #11263 from omacom/fix/t3-theme-migration
Activate T3 theme on existing installs
2026-09-10 22:57:36 -04:00
Ryan Hughes 262a779246 Activate T3 theme on existing installs 2026-09-10 22:57:04 -04:00
Spencer Bull 9f066b649e Merge pull request #10755 from spencerbull/add-claude-desktop-ai-menu
Add the Claude desktop app to Install > AI
2026-09-10 20:47:30 -05:00
e3392ef76f Quit the running Claude app before removing it
Electron rewrites ~/.config/Claude for as long as the app runs, so removing the package and deleting the directory while it is open leaves the app running and the directory back within the same second, holding fresh Preferences and crash-reporter state. Driven end to end on an edge worker: remove via the menu with the app open left 11 processes and a recreated ~/.config/Claude; with the app quit first the directory stayed gone. The test stubs pkill so the suite cannot take a developer's own Claude with it, and asserts the remover reached for it.

Co-Authored-By: Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <noreply@openai.com>
2026-09-10 19:26:34 -05:00
9d0849f717 Add the Claude desktop app to Install > AI
Follows the ChatGPT flow: the Install > AI entry runs
omarchy-install-ai-claude in a floating terminal, which installs the
claude-desktop package (Anthropic's Linux desktop beta, repacked from
their Debian repo in omarchy-pkgs) and opens the app. Remove > AI
drops the package along with ~/.config/Claude and ~/.cache/Claude,
the Electron directories the desktop app owns, while keeping
~/.claude, ~/.claude.json, and ~/.cache/claude-cli-nodejs: those
belong to the Claude Code CLI, which ships in its own package and
survives this removal, just as the ChatGPT remover keeps the Codex
CLI.

The menu mark is a new U+E90E glyph in the Omarchy icon font, from
Simple Icons' Claude mark, so it reaches desktops through the next
omarchy-settings release.

Co-Authored-By: Fable 5 <noreply@anthropic.com>
Co-Authored-By: Codex XHigh <noreply@openai.com>
2026-09-09 22:01:35 -05:00
Spencer Bull 8ea5151639 Merge pull request #10846 from omacom/fix-hermes-desktop-stamp-import
Fix Hermes desktop installation and align menu icons
2026-09-09 18:24:44 -05:00
David Heinemeier HanssonandClaude Opus 5 5ead870507 Add basecamp (basecamp-cli) as a lazy-installed mise tool (#10943)
Mirrors the hey-cli stub: the wrapper in ~/.local/bin installs and
upgrades through mise on first run, so the CLI tracks releases instead
of going stale as a manually dropped binary.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 15:13:43 +02:00
David Heinemeier Hansson f38eb42041 Premature to have this included like this
Lots of great discussions, but it's for Omarchy Cinque, if it happens.
This repo is for Quattro for now.
2026-09-09 11:38:23 +02:00
Spencer Bull 1cb960ac43 Use the Hermes desktop portrait for menu icons 2026-09-08 15:02:17 -05:00
Spencer Bull 27f10ffd97 Fix Hermes desktop installation after module split 2026-09-08 12:50:04 -05:00
Ryan Hughes 5b91db503c Credit @Chainfire for the asdcontrol security report
Chainfire (@Chainfire) privately reported the passwordless asdcontrol watchdog reboot on August 25, 2026.

The fix landed in the 4.0.2 security work: #9200 (df819a6f) removed Omarchy's unrestricted sudo grant, while omacom/omarchy-pkgs#242 and omacom/omarchy-pkgs#243 restricted the package's grant. This records the reporter credit omitted from those changes.

Reported-by: Chainfire (https://github.com/Chainfire)
2026-09-08 12:49:55 -04:00
Ryan HughesandAdolanium 131bda36b5 Credit _SiCk // afflicted.sh for sudo expiry validation
Thanks to _SiCk // afflicted.sh for independently reproducing the passwordless sudo persistence issue and reviewing the proposed fix in #7990. The follow-up fix landed in #9387 (945af75a), with the 4.0.3 backport in cf459ba7.

The original boot-cleanup patch was contributed by @Adolanium. Preserve that co-author credit alongside this acknowledgment.

Co-authored-by: Adolanium <94890352+Adolanium@users.noreply.github.com>
2026-09-08 12:45:31 -04:00
David Heinemeier HanssonandClaude Fable 5.1 7e8feb047d Relay the Elgato Cam Link 4K as a 16:9 virtual camera (#10809)
* Relay the Elgato Cam Link 4K as a 16:9 virtual camera

Browser meeting apps such as Zoom's web client ask the Cam Link for a
standard-definition stream, and Chromium settles on the smallest mode it
offers, 640x480. The Cam Link fills that 4:3 frame by cropping its 16:9
input, and the app then paints the frame into a 16:9 tile, so everyone
comes out stretched wide. The web client has no HD switch to avoid it.

Hide the raw capture node from users and re-expose it through v4l2-relayd
as a 1280x720 virtual camera with the same name, so there is still just
one "Cam Link 4K" to pick and no way to negotiate 4:3 from it. udev
starts the relay whenever the Cam Link enumerates and stops it on unplug,
and the relay only pulls frames while something is watching. The sink
runs unsynced because v4l2src stamps each frame with its capture time,
which a synced sink treats as already late and drops.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Take the review fixes for the Cam Link 4K relay

Tie only the device's stop into the relay instance. A start dependency on
it left a job waiting on a device that never comes whenever the base
v4l2-relayd.service is started without a Cam Link attached, since the
package generator wants every configured instance.

Let the loopback unit rerun on each relay start, so a deleted or unloaded
device is recreated on replug instead of the oneshot staying satisfied.

Start the relay outright at the end of the migration. The udev trigger
only starts it when the rule is new to the device, and a failed module
build would otherwise pass silently with the raw camera already hidden.

Run the hardware fix after the Panther Lake kernel swap, as it pulls in a
DKMS module that would otherwise build twice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 14:09:51 +02:00
Ryan Hughes 148945000f Merge pull request #10774 from omacom/fix/legacy-omarchy-font
Retire the stock user icon font missed by Quattro upgrades
2026-09-08 02:38:26 -04:00
Ryan Hughes f5cd244ed0 Retire the stock user icon font missed by Quattro upgrades 2026-09-08 02:36:58 -04:00
Ryan Hughes 726a56ba03 Merge pull request #10772 from omacom/fix/cursor-mise-node
Keep Cursor bundled Node off the mise PATH
2026-09-08 02:25:26 -04:00
Ryan Hughes 138d839b37 Keep Cursor bundled Node off the mise PATH 2026-09-08 02:22:55 -04:00
Ryan Hughes d504061767 Merge pull request #10759 from omacom/fix/broadcom-wl-dkms
Install broadcom-wl-dkms now that Arch dropped the prebuilt module
2026-09-07 23:03:50 -04:00
Ryan Hughes 649c0b7433 Install broadcom-wl-dkms now that Arch dropped the prebuilt module
Arch removed the prebuilt broadcom-wl package on 2026-09-02 and rebuilt
broadcom-wl-dkms with replaces=(broadcom-wl). A replaces entry only helps
upgrades of an already-installed package, so the name is now unresolvable
as an explicit pacman target and the ISO offline mirror download fails
with "target not found: broadcom-wl".

broadcom-wl-dkms depends on dkms, so the explicit dkms in the hardware fix
is redundant; linux-headers stays because the module has to build against
the running kernel.
2026-09-07 22:56:48 -04:00
bjarneo e848f1df97 Merge pull request #10670 from bjarneo/fix/keyboard-layout-switches-wrong-device
Stop the layout widget switching a device nobody types on
2026-09-07 20:59:54 +02:00
David Heinemeier HanssonandClaude Opus 5 446fbc28b1 Start 1Password at a fixed device scale factor (#10673)
1Password reads the display scale itself, the way Electron apps do, so
on a scaled monitor it comes up oversized next to every other window.
Pin it with --force-device-scale-factor=1 and let the compositor scale
it.

The app menu is covered by the packaged .desktop, which we build
ourselves in omarchy-pkgs. This is the other route in: the hotkey runs
the binary directly and never reads that file.


Claude-Session: https://claude.ai/code/session_01JB9phxP56gnP7qSidkkUJE

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 19:56:18 +02:00
Bjarne OeverliandClaude Opus 5 6ee7479879 Stop the layout widget switching a device nobody types on
Clicking the keyboard layout widget switches one device, chosen by
filtering the seat through UNTYPED_KEYBOARDS and then taking whichever
survivor sits furthest through the layout list. That filter has to
recognise every non-keyboard by name, and a laptop registers far more as
a keyboard than it lists.

On a Dell XPS 14, Hyprland reports ten keyboards and one of them is a
keyboard. The filter catches three of the other nine, leaving vendor
hotkey blocks (intel-hid-events, intel-hid-5-button-array,
dell-privacy-driver, dell-wmi-hotkeys) and two HID endpoints ahead of
at-translated-set-2-keyboard, which sorts last. Every click switches
hid-sdw:...-consumer-control instead, so the label cycles convincingly
while typing never changes. Device order is stable across polls, so it
is deterministic rather than a race, and needs no pre-existing bad state.

Switch every keyboard holding the same layout list instead, naming an
absolute index. "next" advances each device from wherever it sits, so a
seat that has already drifted apart stays drifted and merely inverts;
one index converges it in a single click, and a seat in lockstep leaves
the reading nothing to disagree about. Keyboards given their own
kb_layout hold a different list and are left alone, since an index into
this list would not mean the same layout to them.

The evdev KEY bitmap would separate these cleanly - the real keyboard
emits 167 keys, the pseudo-devices at most 19 - but hyprctl devices
reports no capability information, so the switch is taken out from
behind the name filter rather than the filter being lengthened.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 19:47:24 +02:00
David Heinemeier HanssonandClaude Opus 5 a7486beb60 Add Super + Ctrl + Alt + F to toggle a full screen desktop (#10672)
Hiding the top bar and removing the window gaps are the two things you
do to give the screen entirely to your windows, and doing both took two
hands and two hotkeys. `omarchy toggle fullscreen desktop` does them
together.

It only leaves full screen when both halves are in it, so hitting the
hotkey with just the bar hidden (or just the gaps gone) pulls the other
half into line instead of flipping the one you already set.


Claude-Session: https://claude.ai/code/session_01JB9phxP56gnP7qSidkkUJE

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 19:39:27 +02:00