Conversation
And stick with the same gaps setup as all other themes
The launcher resolves each entry's icon through Quickshell.iconPath(), which bottoms out in Qt's QIconLoader / QIcon::fromTheme. That engine caches the theme's directory listing — and null results — for the life of the process, and only re-scans when the icon theme or search paths change. Nothing in Quickshell 0.3 exposes a way to invalidate it, and a QML reload doesn't reset it either (QIconLoader is a QtGui process global, not tied to the QML engine). So when a user installs a new app while the shell is running, its .desktop file is picked up live (DesktopEntries is file-watched and the name appears immediately), but its icon resolves to the cached miss and renders blank until the whole shell is restarted. That's a poor "I just installed this" experience. Fix it without a restart by keeping our own on-disk icon index as a fallback. When themed lookup returns empty, iconSource() consults a name->path map built by scanning the XDG icon dirs and /usr/share/ pixmaps (SVGs first, so scalable wins). The scan runs on startup and on a debounced DesktopEntries change — the same signal that already makes names appear — and swapping the iconIndex property re-evaluates every iconSource() binding, so freshly installed icons show up live. Icons Qt can already resolve are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Run internal monitor toggle recovery before the sleep lock path and retry recovery after Hyprland monitor removal events. This gives dock/lid-close races time to settle before suspend or external-display reconnects leave the session without a safe internal display fallback.
It's using a staggering 250mb RAM
The May 17 picker performance change made activated thumbnail loads asynchronous, which undid the earlier anti-flicker fix and let carousel movement flash blank thumbnails. Keep lazy activation, but load activated thumbnails synchronously so theme/background picker navigation remains stable. Add regression coverage for the thumbnail loading mode.
The colorset is the Monokai Pro Ristretto palette, so the generated themes keep all the accent colors. Brightened muted to Monokai Pro's actual comment color, since comments sit on that key. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The lock service arms a 5s blank timer whenever the screen locks, and input at the lock screen re-arms it. Closing the lid sprays pointer noise over the lock surface, so the timer was routinely armed right before suspend, froze mid-countdown, and fired moments after resume -- blanking the freshly woken unlock screen under the user. Guard the timer with a wall-clock check: if far more time elapsed than the interval, the countdown slept through a suspend, so take a fresh run-up instead of blanking. This also blanks the lock screen 5s after an untouched resume. Two accomplices made the flash worse and hid the real bug: - The clamshell watcher's 2s poll fired an unconditional global DPMS enable whenever no external monitor was active, relighting any blank within 2 seconds (lock-screen blanking never stuck on undocked laptops) and racing the resume modeset. Recovery now only wakes displays when it actually re-enables one. - Every keystroke at the lock screen dispatched a redundant DPMS enable via omarchy-system-wake, forcing extra modesets in the fragile just-resumed DRM state. Brightness "on" now skips the dispatch when every active display is already lit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fixing to screenrecording instead screenrecord that works only when using the alias
Adds shift:both_capslock alongside compose:caps so pressing both Shift keys together toggles real Caps Lock. Caps Lock alone remains the Compose key, and single-Shift behavior is unchanged. Provides an escape hatch when Caps Lock gets stuck on (e.g. after an fcitx5 desync). Closes #5981 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The tree is wholly package-owned, but files can land there unowned (in-place extension work, script-written files), and pacman then aborts the entire upgrade on the file conflict — as happened when copy-url's service worker was renamed to background-2.js. The conflict check runs before any hooks or scriptlets, so the package itself can't recover; the update command has to allow the overwrite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
The background plugin ran a 100ms Timer that spawned a readlink subprocess ~10x/sec for the life of the shell, purely to notice wallpaper changes. Wallpaper updates already arrive over IPC (omarchy-theme-bg-set calls `background set`, omarchy-theme-set calls `background themeTransition`), and the initial wallpaper is read once in Component.onCompleted, so the poll was redundant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The indicators widget broadcast a refresh every 2s, fanning out to four status subprocesses (nightlight, idle, reminder, screen-recording), and NightLight/StayAwake each ran an additional 5s poll. On an idle desktop this was the dominant source of process churn (~33 of ~53 forks/sec in a VM). The state-changing commands already push `omarchy.indicators refresh` over IPC, so the polling was redundant. Drop the 2s broadcast and the two 5s timers; indicators now refresh at startup and on the IPC push. Also fix three callers that pushed to the wrong target `Indicators` instead of `omarchy.indicators` (screen recording, notification silencing, and the omarchy-shell help example) — those pushes silently failed and only appeared to work because the poll masked them. Idle fork rate drops ~53/s to ~20/s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The monitor panel polled `omarchy-monitor-state` every 5s (26 forks per call) and the network panel polled `omarchy-network-status` every 3s, both with `running: true` rather than gating like the sibling panels. Monitor: gate the poll on `opened` (brightness/scale are only shown in the open panel, which already refreshes on open) and drive the bar glyph from Quickshell.screens instead of the polled display list, so monitor count stays correct without polling. Network: the bar pill needs live-ish state, so keep polling but at 10s instead of 3s. (Deriving the pill from the native Networking service would remove the poll entirely; left as a follow-up since it needs Wi-Fi state testing.) Idle fork rate drops ~20/s to ~14/s. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each `bash -lc` starts a login shell that re-sources the profile (mise activation, /etc/profile.d) on every invocation — ~16 forks per call versus ~2 for `bash -c` — which taxes every menu/panel/launcher action the shell shells out for. The session already exports PATH and env to the shell, so omarchy commands resolve fine under `bash -c`. Switch the internal/omarchy-owned spawns (theme+background switches, brightness, monitor scaling, DNS, lock/fingerprint, keyboard-layout probe, voxtype status, and the `:`/printf state-file writes) to `bash -c`. Leave `bash -lc` on the sites that run user-configurable commands (custom bar-widget exec, menu provider/guard scripts, launcher scan commands, configurable idle/screensaver command), where a user's command may rely on their login environment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Great work!!! SUPER + ALT + [ / ] Can we have a different key to / as in german / swiss keyboards, this is available via shift. So it would be SUPER+ALT+SHIFT+7. Usually having / and \ are not working keyboard shortcuts and need manual fixing. |
|
BTW: I can suggest alternatives and provide an MR if we're open to this change incl. past shortcuts... |
The pill was populated by polling omarchy-network-status (previously every 3s, then 10s). Derive kind/signalStrength directly from the Quickshell.Networking service instead: wired-connected → ethernet (preferred, matching the default-route device), else a connected Wi-Fi network → wifi with its signal, else disconnected. The service's properties are change-notified, so the pill updates on connect/ disconnect and signal changes with no polling and no subprocess. Removes the last periodic poll from the bar; the label/frequency pill fields were write-only and are dropped. Verified live: pill tracks ethernet → disconnected → ethernet in real time as the wired device goes down and up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
omarchy-hyprland-monitor-watch ran poll_clamshell_state() every 2s for the whole session, and each pass forks omarchy-hyprland-monitor-clamshell plus its hyprctl/jq/monitor-* children. Clamshell (lid) handling can only ever apply to a machine with a lid, so on desktops and VMs this was pure churn — the single largest remaining source of idle process wakeups (~3 forks/sec on an otherwise idle desktop). Gate the poll behind a new omarchy-hw-laptop helper (lid button, or a laptop DMI chassis type as a fallback). The event-driven socat watch on Hyprland monitor add/remove is unchanged, so monitor hotplug still reconciles everywhere; only the periodic lid poll is now laptop-only. Verified on a desktop: steady-state omarchy-hyprland-* forks drop from ~3/sec to zero, socat watch still present. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The reconciliation poll (added in "Fix clamshell display recovery") is a backstop for lid transitions the Hyprland switch binds can miss across suspend/resume. But the internal panel is only ever disabled while the laptop is docked — lid shut with an external monitor active — so the poll has nothing to reconcile when undocked. Running it 24/7 on every laptop wakes the CPU every 2s for no reason, which is exactly the case where battery matters most. Start the poll when an external monitor is present and stop it when the last one goes away (driven by the socat monitor-add/remove watch), gated on omarchy-hw-laptop. Undocked laptops and desktops now never poll; a docked laptop keeps the 2s recovery poll. Switch the event reader from a pipe to process substitution so it runs in the main shell and can manage the poll's lifetime. Desktop verified: no poll runs even with external monitors attached. The docked-laptop start/stop path needs a check on real laptop hardware. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The media service ran a 500ms repeat timer calling syncPlayingOrder() for the whole session — two CPU wakeups a second even with nothing playing. syncPlayingOrder only depends on the set of MPRIS players and each player's isPlaying state, both of which the Mpris service already signals. Replace the timer with onPlayersChanged (players appearing/disappearing) plus an Instantiator that connects isPlayingChanged for each live player, and a Component.onCompleted for the initial sync. Verified with a test MPRIS player: play/pause and player add/remove all update the active player with no periodic timer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Guards the dock-gating in omarchy-hyprland-monitor-watch: the poll runs only when omarchy-hw-laptop and an external monitor are both present, via sync_poll_state, with the event loop fed by process substitution so it can start/stop the poll. Behaviourally simulated (stubbed hw checks + synthetic monitor events): the poll runs only while docked and stops on undock; a desktop or undocked laptop never polls. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
system-config-printer ships /etc/xdg/autostart/print-applet.desktop, so installing it for the printer GUI also starts a ~24 MiB Python tray applet in every session whose only job is print-job notifications. Override it with a Hidden=true entry in config/autostart (same mechanism already used for fcitx5 and limine-snapper-notify), so the applet no longer autostarts. Printing and the system-config-printer GUI are unaffected. Verified: with the override in place, systemd's xdg-autostart generator no longer produces app-print\x2dapplet@autostart.service. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
gum_env.lua is fed into the compositor environment via hl.env at login, but that environment is captured once and is not refreshed on a theme switch. Terminals launched through uwsm-app inherit the caller's environment (scopes don't read systemctl --user set-environment), so a floating terminal would show the login-time theme's gum colors. Extract the export logic into a sourced omarchy-restart-gum helper and source it from the presentation terminal launcher so gum widgets match the active theme. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
The Copy URL shortcut repair checked the outer script's yes variable, which never reached the user-transition heredoc's bash process, so the upgrade died with "yes: unbound variable" under set -u whenever a browser was running with the old extension id in its Preferences. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The user-transition script is fed to bash on stdin, so the browser-close gum confirm read the script itself: it auto-declined and swallowed the remaining script text, leaving bash to fail on a mid-construct syntax error. The outer confirm and reboot prompts had the same exposure when the script runs via curl | bash. Read all three from /dev/tty. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Extract run_as_user_omarchy and run_as_user_wayland_session helpers to replace ten hand-rolled run_as_user env blocks - Declare the retired user-unit list once instead of three times - Use git ls-files --others to find user-added theme backgrounds instead of diffing against the tracked list by hand - Stop rewriting the SDDM 10-theme/10-wayland confs the omarchy package already installs, and drop the duplicate [Theme] section from 99-omarchy-login.conf - Drop the legacy-path rewrite in the theme hyprland.conf shim; the user transition already rewrote those references - Remove dead code: the unreachable channel re-validation, the declare -F guard in cleanup_on_exit, and the unset block at the end of the user-transition script Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Suppression was enabled only after cleanup_legacy_user_paths had already moved ~/.local/share/omarchy aside, so the live session could auto-reload during the swap window and pop "source= globbing error: found no match" for every legacy hyprland.conf source line. Enable suppression as the first step of the upgrade sequence instead; the EXIT trap still restores it if the upgrade dies early. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Quattro Alpha
Omarchy 4 aka Quattro is the biggest release since the project started. The entire desktop shell has been reimagined in Quickshell: the bar, launcher, menus, notifications, on-screen displays, control panels, lock screen, and polkit agent now all live inside a single long-running shell process with a plugin architecture. That means Waybar, Walker, Mako, SwayOSD, hyprlock, hypridle, swaybg, and polkit-gnome are all gone, replaced by one coherent, fully-themed, IPC-scriptable shell.
You can upgrade an existing Omarchy installation to Quattro with the following command:
curl -fsSL https://omarchy.org/upgrade-to-quattro-dev | bashThis will put you on the alpha development version. So not something that's recommended for production systems. Ensure you have a good backup first!
Headline Features
The Shell
SUPER + SHIFT + CTRL + arrowsworks too)omarchy plugin add <git-url>(landing disabled for code review first) by @ryanrhughesSUPER + SPACE)SUPER + SHIFT + ALT + ,), do-not-disturb, deduping, and replay of recent history after restartsSUPER + CTRL + V)SUPER + CTRL + E) and native volume/brightness/media OSDsSUPER + CTRL + A), Bluetooth (SUPER + CTRL + B), Network (SUPER + CTRL + W), Display (SUPER + CTRL + D), and Power (SUPER + CTRL + P)~/.config/omarchy/extensions/omarchy-menu.jsonc)Theming & Aesthetics
SUPER + SHIFT + CTRL + SPACE)SUPER + CTRL + SPACE)Apps & Defaults
SUPER + SHIFT + W)Capture
SUPER + ALT + [ / ].RETURNwhile the region picker is open.rsw/lsw/dswcommands.Controls
o.bind("SUPER + SHIFT + W", "Omawrite", { launch = "omawrite" })) by @ryanrhughesSUPER + ALT + HOME/SUPER + HOMESUPER + ALT + K) and new-pane/split bindings for tmux, kitty, ghostty, and alacritty by @ryanrhughes, @vtmx, @heymaikol, and @dhhNetworking/Connections
System & Upgrade
/etc, so updates flow through pacman by @ryanrhughesomarchy update(bypassable viaOMARCHY_ALLOW_DIRECT_PACMAN=1) by @ryanrhughesmupalias to get instant updates) by @dhhpre-refresh-pacman.dhooks for custom repository support by @tyvsmithFixes
fipand friends misparsing under zsh by @pkwagnerCTRL + BACKSPACEby @RushiChagantiFeature presentations
The theme switcher
Switching themes is now a more visual affair: a filterable carousel of live previews for every installed theme, opened with
SUPER + SHIFT + CTRL + SPACEor via Style > Theme. You can see the new bar riding on top too.The background switcher
Backgrounds get the same treatment on
SUPER + CTRL + SPACE: flip through the current theme's backgrounds (plus any you've added) and see exactly what you're picking.The launcher
Walker has been replaced by a native launcher with fuzzy and acronym matching, live icon indexing (freshly-installed apps show up with their icons immediately), and the ability to hide entries you never use. Still on
SUPER + SPACE.The Omarchy menu
The menu is now a native, filterable command palette living inside the shell. Same
SUPER + ALT + SPACEmuscle memory, instant response, and extensible through a JSONC file if you want to add your own entries.Control panels
The bar widgets now open real control panels. Audio (
SUPER + CTRL + A) has output/input device switching and volume control:Network (
SUPER + CTRL + W) shows live throughput, ping, packet loss, a one-click speed test, DNS provider selection, and nearby networks:And weather now has a proper forecast panel, which can be pinned to a chosen location instead of following your IP around:
A bar you can grab
There's no settings panel for the bar — you just grab it. Click and hold any empty stretch of bar and drag it toward a screen edge, and a ghost slab previews where it will dock. Drop it on the left or right and it turns into a vertical bar. Double-click empty bar space to toggle transparency. Widgets are added, removed, and rearranged with
omarchy bar plugin, and third-party widgets install straight from git.Privilege escalation with context
Omarchy now uses pkexec/polkit for privileged operations, with a themed prompt that tells you exactly what command you're authorizing before you type your password.
Omawrite
Typora is out, and Omawrite is in. A dead-simple Markdown writing app that opens in a blink, autosaves as you type, and stays out of the way. Bound to
SUPER + SHIFT + W. Free software.Omacut
A dead-simple video trimmer to go with it. Drop in a clip — like the screen recordings Omarchy takes — drag the handles on the filmstrip, and export the cut with ffmpeg doing the heavy lifting.