Hyprland 0.56 fixed premultiplication in the color-management shader
(hyprwm/Hyprland#14403), so the same opacity values now render visibly
more transparent than on 0.55. Raise each value to its perceptual
equivalent (a^(1/2.2)) to restore the previous look.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hyprland 0.56 fixed premultiplication in the color-management shader
(hyprwm/Hyprland#14403), so the same opacity values now render visibly
more transparent than on 0.55. Raise each value to its perceptual
equivalent (a^(1/2.2)) to restore the previous look.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Ports #6092 from master: the video-app opacity opt-out only matched
Chrome/Chromium on the default profile, so Brave, Edge, and non-default
profiles kept the translucent default-opacity styling.
Co-Authored-By: Zeus-Deus <github.commits@widow.cc>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Set misc:initial_workspace_tracking = 0 so new windows appear on the currently
active workspace rather than the one their process was first launched on.
Without this, file-picker dialogs drawn by xdg-desktop-portal-gtk (browser
Open/Save, GTK app choosers, etc.) always open on the workspace where the portal
process started at login (typically workspace 1) instead of following the app
that requested them. So a Save dialog triggered from a browser on workspace 2
pops up on workspace 1, out of view.
Trade-off: an app launched on one workspace that switches away before its window
maps will now open on the new active workspace. In practice the dialog-follows-app
behavior is the more intuitive default.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
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>
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>
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.
The git-era flow installed Omarchy to ~/.local/share/omarchy. In the
package-based flow it lives at /usr/share/omarchy (or, in dev mode, at
the path /etc/omarchy.conf's OMARCHY_PATH points at). Files that hard-
coded the old path broke on package installs:
- default/bash/rc: sourced ~/.local/share/omarchy/default/bash/*, so a
fresh user's terminal logged ENOENT for every line. Now sources from
$OMARCHY_PATH with /usr/share/omarchy as the safe default if the var
is unset.
- config/systemd/user/omarchy-recover-internal-monitor.service:
ExecStart pointed at %h/.local/share/omarchy/bin/. The script ships
to /usr/bin via the omarchy-installer package; point straight there.
- install/config/xcompose.sh: wrote an XCompose include line pointing
at the user-home path; use /usr/share/omarchy/ directly.
- default/hypr/paths.lua and config/hypr/hyprland.lua: fallback when
OMARCHY_PATH is unset is /usr/share/omarchy, not the home path.
Dev-only scripts (omarchy-dev-add-migration, omarchy-reinstall-git) and
the SKILL.md docs still reference the old path; those are separate
cleanups since they don't affect a fresh install's runtime.
A pass over the install scripts, dev-tools commands, and Hyprland Lua
files that I had stuffed with explain-everything preambles. Most of
those rationales (which files ship where, why hyprctl setenv doesn't
suffice, etc.) belong in commit messages or PR descriptions, not in
code people have to read forever. Kept the few comments that document
genuinely non-obvious behaviour: the keybind-env reason for hl.env in
envs.lua, why the runtime PAM seds stay scripted in
increase-lockout-limit, the chroot/--now distinction in chroot.sh, and
the dev-pkg-test split-install reason.
Two related fixes for omarchy-dev-link to actually affect Hyprland keybinds:
default/hypr/paths.lua: prefer /etc/omarchy.conf over the process env.
hyprctl setenv updates Hyprland's process env, but the user-reported case
shows it doesn't reach bind-exec dispatchers because their env is
captured at config-load time. Reading the dev-link conf directly means
paths.omarchy_path is correct on every hyprctl reload regardless of
whether the launching Hyprland session re-read its env.
default/hypr/envs.lua: explicitly hl.env("OMARCHY_PATH", ...) and
hl.env("PATH", "$OMARCHY_PATH/bin:$PATH") so keybind dispatchers (and
everything else spawned by Hyprland) inherit the dev-link values. PATH
is built with a dedup pass so reloads don't accumulate the bin/ prefix.
Tested locally: paths.lua reads /etc/omarchy.conf correctly; lua syntax
of both files validates with luac -p.
The /etc/profile.d/omarchy.sh default for OMARCHY_PATH was being clobbered
by shipped config files that re-export the variable to the old script-mode
path. In package mode, every login shell, UWSM session, and Hyprland
autostart was effectively reversing the migration. Fix:
- default/bashrc: source from $OMARCHY_PATH/default/bash/rc; default
OMARCHY_PATH to /usr/share/omarchy if not set (so the source line
works in any boot order, including non-login interactive shells).
- default/bash/envs: change 'export OMARCHY_PATH=$HOME/...' to
'export OMARCHY_PATH=${OMARCHY_PATH:-/usr/share/omarchy}' so the
profile.d default and install.sh script-mode override both win.
- config/uwsm/env: same defaulting pattern. UWSM may not source
profile.d, so the inline default still matters.
- default/hypr/autostart.lua: quickshell launched from $OMARCHY_PATH/shell
(not literal $HOME path). The bash that runs hl.exec_cmd sees
OMARCHY_PATH propagated from UWSM env.
- config/chromium-flags.conf: --load-extension hard-codes
/usr/share/omarchy/... because chromium doesn't expand env vars or
'~'. The omarchy-dev-link workflow symlinks /usr/share/omarchy to a
checkout.
- bin/omarchy-install-browser: same chromium-flag path correction for
brave-origin-beta-flags.conf.