Merge remote-tracking branch 'origin/quattro' into fix-snapshot-locate-and-timeline-leak
# Conflicts: # docs/file-layout.md
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
echo "Gate sudo and polkit fingerprint auth behind the lid state (password when the lid is shut)"
|
||||
|
||||
# Existing fingerprint setups have pam_fprintd first in /etc/pam.d/sudo and
|
||||
# /etc/pam.d/polkit-1 but no lid gate, so a closed-lid sudo or pkexec would
|
||||
# block on the unreachable reader for the full pam_fprintd timeout before
|
||||
# offering the password. Insert a pam_exec gate before pam_fprintd that skips
|
||||
# fingerprint while the lid is closed. New setups already get this from
|
||||
# omarchy-setup-security-fingerprint.
|
||||
#
|
||||
# The gate points at the fixed /usr/bin path the omarchy package always
|
||||
# provides, so it keeps working across package installs and dev-link (which
|
||||
# overlays $OMARCHY_PATH but leaves /usr/bin untouched). pam_exec needs a
|
||||
# literal absolute path — it does not expand env vars.
|
||||
|
||||
gate="auth [success=1 default=ignore] pam_exec.so quiet /usr/bin/omarchy-hw-laptop-closed"
|
||||
|
||||
for pam in /etc/pam.d/sudo /etc/pam.d/polkit-1; do
|
||||
if [[ -f $pam ]] &&
|
||||
grep -q 'pam_fprintd\.so' "$pam" &&
|
||||
! grep -q 'omarchy-hw-laptop-closed' "$pam"; then
|
||||
sudo sed -i "/pam_fprintd\.so/i $gate" "$pam"
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,17 @@
|
||||
echo "Add tmux hooks that surface waiting windows in the bar"
|
||||
|
||||
tmux_config="$HOME/.config/tmux/tmux.conf"
|
||||
|
||||
if [[ -f $tmux_config ]] && ! grep -q 'alert-bell' "$tmux_config"; then
|
||||
cat >>"$tmux_config" <<'EOF'
|
||||
|
||||
# Alerts
|
||||
set-hook -g alert-bell 'run-shell -b "omarchy-shell -q omarchy.indicators refresh"'
|
||||
set-hook -g alert-activity 'run-shell -b "omarchy-shell -q omarchy.indicators refresh"'
|
||||
set-hook -g alert-silence 'run-shell -b "omarchy-shell -q omarchy.indicators refresh"'
|
||||
set-hook -g after-select-window 'run-shell -b "omarchy-shell -q omarchy.indicators refresh"'
|
||||
set-hook -g client-session-changed 'run-shell -b "omarchy-shell -q omarchy.indicators refresh"'
|
||||
EOF
|
||||
|
||||
omarchy-restart-tmux
|
||||
fi
|
||||
@@ -0,0 +1,12 @@
|
||||
echo "Regenerate mise wrappers to stop them recursing through PATH"
|
||||
|
||||
for wrapper in "$HOME/.local/bin"/*; do
|
||||
[[ -f $wrapper && -x $wrapper ]] || continue
|
||||
|
||||
package=$(sed -n 's/^mise use -g "\(.*\)"$/\1/p' "$wrapper")
|
||||
bin=$(sed -n 's/^exec "\(.*\)" "\$@"$/\1/p' "$wrapper")
|
||||
|
||||
if [[ -n $package && -n $bin ]]; then
|
||||
omarchy-mise-install "$package" "$(basename "$wrapper")" "$bin"
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,19 @@
|
||||
echo "Keep Wi-Fi power save off for lower latency"
|
||||
|
||||
as_root() {
|
||||
if (( EUID == 0 )); then
|
||||
"$@"
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
as_root nmcli general reload conf >/dev/null 2>&1 || true
|
||||
|
||||
# NetworkManager only applies wifi.powersave when a connection activates, so
|
||||
# also switch it off directly for the running session.
|
||||
shopt -s nullglob
|
||||
for wireless in /sys/class/net/*/wireless; do
|
||||
iface=$(basename "$(dirname "$wireless")")
|
||||
as_root iw dev "$iface" set power_save off 2>/dev/null || true
|
||||
done
|
||||
@@ -0,0 +1,17 @@
|
||||
echo "Unpack the initramfs synchronously so Plymouth survives early boot"
|
||||
|
||||
# Kernel 7.1 unpacks the initramfs asynchronously, which races /init: the
|
||||
# early /proc, /sys, /dev, and /run mounts fail while unpacking settles, so
|
||||
# plymouthd exits when it can't read /proc/cmdline and encrypted boots fall
|
||||
# back to an unthemed text LUKS prompt. Force synchronous unpacking until the
|
||||
# race is fixed upstream. The packaged omarchy-defaults.conf now carries the
|
||||
# same parameter for fresh installs.
|
||||
|
||||
if omarchy-cmd-present limine-mkinitcpio &&
|
||||
[[ -f /etc/limine-entry-tool.d/omarchy-defaults.conf ]] &&
|
||||
! grep -rqs "initramfs_async" /etc/limine-entry-tool.d/ /etc/default/limine; then
|
||||
echo 'KERNEL_CMDLINE[default]+=" initramfs_async=0"' |
|
||||
sudo tee -a /etc/limine-entry-tool.d/omarchy-defaults.conf >/dev/null
|
||||
|
||||
sudo limine-mkinitcpio
|
||||
fi
|
||||
@@ -0,0 +1,17 @@
|
||||
echo "Track tmux output while its terminal is unfocused"
|
||||
|
||||
tmux_config="$HOME/.config/tmux/tmux.conf"
|
||||
|
||||
if [[ -f $tmux_config ]] && ! grep -q 'client-focus-out\[100\].*omarchy-tmux-alert track' "$tmux_config"; then
|
||||
sed -i \
|
||||
-e 's|^set-hook -g after-select-window .*|set-hook -g after-select-window '"'"'run-shell -b "omarchy-tmux-alert track #{window_id} #{window_activity}"'"'"'|' \
|
||||
-e 's|^set-hook -g client-session-changed .*|set-hook -g client-session-changed '"'"'run-shell -b "omarchy-tmux-alert track #{window_id} #{window_activity}"'"'"'|' \
|
||||
"$tmux_config"
|
||||
|
||||
cat >>"$tmux_config" <<'EOF'
|
||||
set-hook -g client-focus-out[100] 'run-shell -b "omarchy-tmux-alert track #{window_id} #{window_activity}"'
|
||||
set-hook -g client-focus-in[100] 'run-shell -b "omarchy-tmux-alert track #{window_id} #{window_activity}"'
|
||||
EOF
|
||||
|
||||
omarchy-restart-tmux
|
||||
fi
|
||||
@@ -0,0 +1,10 @@
|
||||
echo "Install the speaker tuning for XPS 2026 14/16"
|
||||
|
||||
# Speaker tunings are PipeWire filter-chain drop-ins gated on a hardware
|
||||
# predicate, so this is a no-op on machines without one. The limiter is an LV2
|
||||
# plugin and the graph will not instantiate without it.
|
||||
|
||||
if omarchy-audio-tuning match >/dev/null 2>&1; then
|
||||
omarchy-pkg-add lsp-plugins-lv2
|
||||
omarchy-audio-tuning on
|
||||
fi
|
||||
@@ -0,0 +1,24 @@
|
||||
echo "Tune reclaim for swap on zram"
|
||||
|
||||
# Everything here only applies the shipped config early; boot picks it up
|
||||
# regardless. Nothing is worth failing the migration chain over, so each step
|
||||
# falls back to asking for a reboot.
|
||||
|
||||
# Load our file specifically rather than --system, which returns nonzero for
|
||||
# any invalid key in any admin sysctl file on the machine.
|
||||
sudo sysctl -p /etc/sysctl.d/99-omarchy-sysctl.conf >/dev/null || true
|
||||
|
||||
if sudo systemctl daemon-reload; then
|
||||
# Resizing swaps the device off first, which faults every stored page back
|
||||
# into memory. That's only cheap while it's empty, so a device under
|
||||
# pressure keeps its old size until the next boot. A device that doesn't
|
||||
# exist yet reads as empty, which is what we want: the restart brings it up
|
||||
# against the unit daemon-reload just generated.
|
||||
zram_used=$(awk '$1 == "/dev/zram0" {print $4}' /proc/swaps)
|
||||
|
||||
if [[ ${zram_used:-0} == 0 ]] && sudo systemctl restart dev-zram0.swap; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
omarchy-state set reboot-required
|
||||
@@ -0,0 +1,25 @@
|
||||
echo "Give the pre-suspend lock a window it can actually finish in"
|
||||
|
||||
# logind's five second default expires while Quickshell is still securing the
|
||||
# session on lid close, and it suspends regardless. The shipped drop-in raises
|
||||
# InhibitDelayMaxSec, but logind only reads it on reload.
|
||||
#
|
||||
# Reload rather than restart: restarting systemd-logind tears down the session.
|
||||
sudo systemctl reload systemd-logind >/dev/null 2>&1 || true
|
||||
|
||||
# Check the property logind actually enforces, not the reload's exit status: a
|
||||
# reload that returns success while the drop-in is missing or unparsed leaves
|
||||
# the old five second window in place. omarchy-system-sleep-lock reads this same
|
||||
# property at runtime, so it stays correct either way -- the reboot flag is only
|
||||
# about getting the wider window to take effect.
|
||||
#
|
||||
# Both reads have to survive failing: a missing drop-in or an unreachable logind
|
||||
# is the very condition being tested for, and migrations run under -e.
|
||||
dropin=/etc/systemd/logind.conf.d/20-inhibit-delay.conf
|
||||
expected_s=$(sed -n 's/^InhibitDelayMaxSec=//p' "$dropin" 2>/dev/null || true)
|
||||
effective_us=$(busctl get-property org.freedesktop.login1 /org/freedesktop/login1 \
|
||||
org.freedesktop.login1.Manager InhibitDelayMaxUSec 2>/dev/null | awk '{print $2}' || true)
|
||||
|
||||
if [[ -z $expected_s || $effective_us != $((expected_s * 1000000)) ]]; then
|
||||
omarchy-state set reboot-required
|
||||
fi
|
||||
@@ -0,0 +1,41 @@
|
||||
echo "Move the bar indicators to the left of the clock"
|
||||
|
||||
config_file="$HOME/.config/omarchy/shell.json"
|
||||
|
||||
if [[ -s $config_file ]]; then
|
||||
tmp=$(mktemp)
|
||||
jq '
|
||||
def entry_id:
|
||||
if type == "string" then
|
||||
.
|
||||
elif type == "object" then
|
||||
(.id // "")
|
||||
else
|
||||
""
|
||||
end;
|
||||
|
||||
def entry_index($id):
|
||||
[range(0; length) as $i | select((.[$i] | entry_id) == $id) | $i][0];
|
||||
|
||||
def place_indicators_before_clock:
|
||||
if type != "array" then
|
||||
.
|
||||
else
|
||||
(entry_index("omarchy.clock")) as $clock_index |
|
||||
(entry_index("omarchy.indicators")) as $indicators_index |
|
||||
if $clock_index == null or $indicators_index == null or $indicators_index < $clock_index then
|
||||
.
|
||||
else
|
||||
. as $entries |
|
||||
($entries[$indicators_index]) as $indicators_entry |
|
||||
($entries | del(.[$indicators_index])) as $without_indicators |
|
||||
($without_indicators | entry_index("omarchy.clock")) as $new_clock_index |
|
||||
$without_indicators[0:$new_clock_index] + [$indicators_entry] + $without_indicators[$new_clock_index:]
|
||||
end
|
||||
end;
|
||||
|
||||
.bar.layout.center |= place_indicators_before_clock
|
||||
' "$config_file" >"$tmp" && mv "$tmp" "$config_file" || rm -f "$tmp"
|
||||
fi
|
||||
|
||||
omarchy-restart-shell
|
||||
@@ -0,0 +1,22 @@
|
||||
echo "Repair Neovim theme symlinks the earlier relink missed"
|
||||
|
||||
theme_link="$HOME/.config/nvim/lua/plugins/theme.lua"
|
||||
current_absolute_target="$HOME/.local/state/omarchy/current/theme/neovim.lua"
|
||||
current_relative_target="../../../../.local/state/omarchy/current/theme/neovim.lua"
|
||||
|
||||
[[ -L $theme_link ]] || exit 0
|
||||
|
||||
target=$(readlink "$theme_link") || exit 0
|
||||
|
||||
# Already pointing at the state directory.
|
||||
[[ $target == "$current_relative_target" || $target == "$current_absolute_target" ]] && exit 0
|
||||
|
||||
# 1781158082.sh matched an explicit list of legacy spellings and missed at least
|
||||
# one ("../../../../.config/omarchy/current/theme/neovim.lua"), leaving those
|
||||
# links dangling. Match the shared suffix instead so every spelling is repaired.
|
||||
case "$target" in
|
||||
*/omarchy/current/theme/neovim.lua) ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
|
||||
ln -sfn "$current_relative_target" "$theme_link"
|
||||
@@ -0,0 +1,36 @@
|
||||
echo "Move zram tuning to a vendor drop-in"
|
||||
|
||||
zram_conf="${OMARCHY_ZRAM_CONF:-/etc/systemd/zram-generator.conf}"
|
||||
zram_dropin="${OMARCHY_ZRAM_DROPIN:-/usr/lib/systemd/zram-generator.conf.d/90-omarchy.conf}"
|
||||
|
||||
# The tuning ships as /usr/lib/systemd/zram-generator.conf.d/90-omarchy.conf.
|
||||
# Drop-ins outrank the main config file, so a leftover /etc copy decides nothing
|
||||
# and only implies /etc is where zram gets configured.
|
||||
|
||||
[[ -f $zram_conf ]] || exit 0
|
||||
|
||||
# Only once the replacement is on disk. zram-generator makes no device at all
|
||||
# when nothing configures one, so until the drop-in lands the /etc copy is the
|
||||
# only thing standing between this machine and no zram swap. The update pipeline
|
||||
# installs packages before it runs migrations, but a dev checkout carries
|
||||
# migrations from a release the installed package does not have yet.
|
||||
[[ -f $zram_dropin ]] || exit 0
|
||||
|
||||
# Package-owned copies go away with their package on upgrade.
|
||||
pacman -Qo "$zram_conf" &>/dev/null && exit 0
|
||||
|
||||
# archinstall writes exactly a [zram0] section with one compression-algorithm
|
||||
# line. Anything else is a deliberate local override. grep exits 1 on a config
|
||||
# that sets nothing at all, which omarchy-migrate's -e would take as a failed
|
||||
# migration and block every migration behind this one.
|
||||
settings=$(grep -vE '^[[:space:]]*([#;]|$)' "$zram_conf" | tr -d '[:space:]') || true
|
||||
|
||||
if [[ -z $settings || $settings =~ ^\[zram0\]compression-algorithm=[[:alnum:]-]+$ ]]; then
|
||||
# A refused sudo just leaves the file for next time; tidying is not worth
|
||||
# failing the migration chain over.
|
||||
sudo rm -f "$zram_conf" || true
|
||||
else
|
||||
echo "Keeping $zram_conf; it has local edits."
|
||||
echo "Omarchy's drop-in overrides it. Move your changes to"
|
||||
echo "/etc/systemd/zram-generator.conf.d/99-local.conf to keep them in effect."
|
||||
fi
|
||||
@@ -0,0 +1,17 @@
|
||||
echo "Switch fingerprint support back to stock libfprint"
|
||||
|
||||
# libfprint-git existed to carry the focaltech_moc driver and the FocalTech
|
||||
# FT9349 device ID (2808:a97a) before any release shipped them. libfprint
|
||||
# 1.94.100 has both, so fingerprint setups go back to the stock Arch package.
|
||||
|
||||
# The remove/install pair below isn't one transaction: if the install failed
|
||||
# on a previous run, libfprint-git is already gone but fprintd is left with
|
||||
# no libfprint — the elif finishes the job on rerun.
|
||||
if pacman -Q libfprint-git &>/dev/null; then
|
||||
# Deps-only removal keeps fprintd installed while its libfprint
|
||||
# dependency is swapped out underneath it.
|
||||
sudo pacman -Rdd --noconfirm libfprint-git
|
||||
omarchy-pkg-add libfprint
|
||||
elif pacman -Q fprintd &>/dev/null && ! pacman -Q libfprint &>/dev/null; then
|
||||
omarchy-pkg-add libfprint
|
||||
fi
|
||||
@@ -0,0 +1,38 @@
|
||||
echo "Resize zram to match the shipped config"
|
||||
|
||||
# 90-omarchy.conf changed the device size. The migration that first applied the
|
||||
# zram tuning is one-shot, so machines that already ran it have the new file on
|
||||
# disk and the old device still running; nothing would pick the size up until
|
||||
# something else rebooted them.
|
||||
|
||||
zram_disksize=${OMARCHY_ZRAM_DISKSIZE:-/sys/block/zram0/disksize}
|
||||
swaps=${OMARCHY_SWAPS:-/proc/swaps}
|
||||
|
||||
# The size is an expression, and the generator is the only thing that evaluates
|
||||
# it. Ask it what the shipped config comes to rather than repeating the
|
||||
# arithmetic here, where the two would drift apart on the next tuning change.
|
||||
units=$(mktemp -d)
|
||||
trap 'rm -rf "$units"' EXIT
|
||||
desired_mb=$(/usr/lib/systemd/system-generators/zram-generator "$units" 2>&1 |
|
||||
grep -oP '/dev/zram0 with \K[0-9]+') || true
|
||||
|
||||
actual_bytes=$(cat "$zram_disksize" 2>/dev/null) || actual_bytes=0
|
||||
|
||||
# A device already at the right size needs neither a restart nor a reboot,
|
||||
# whether an earlier boot picked the config up or another user got here first.
|
||||
if [[ -n $desired_mb && $actual_bytes == $((desired_mb * 1024 * 1024)) ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if sudo systemctl daemon-reload; then
|
||||
# Resizing swaps the device off first, which faults every stored page back
|
||||
# into memory. That's only cheap while it's empty, so a device under
|
||||
# pressure keeps its old size until the next boot.
|
||||
zram_used=$(awk '$1 == "/dev/zram0" {print $4}' "$swaps")
|
||||
|
||||
if [[ ${zram_used:-0} == 0 ]] && sudo systemctl restart dev-zram0.swap; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
omarchy-state set reboot-required
|
||||
@@ -0,0 +1,39 @@
|
||||
echo "Only check for pending migrations at login, not on every package update"
|
||||
|
||||
# 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 migrations that were already being applied in the
|
||||
# visible update terminal. Retire the watcher and keep only the once-per-login
|
||||
# check, now named after the command it runs.
|
||||
|
||||
wants_dir="$HOME/.config/systemd/user/graphical-session.target.wants"
|
||||
|
||||
systemctl --user daemon-reload >/dev/null 2>&1 || true
|
||||
|
||||
# The watcher's unit file is already gone, but it stays loaded in a session that
|
||||
# started before this update, so stop it before it can fire again.
|
||||
systemctl --user stop omarchy-update-user-notify.path >/dev/null 2>&1 || true
|
||||
|
||||
# Enable the replacement before dropping the old enablement, so a failure here
|
||||
# can never leave a user with no notifier at all. Enable without --now: this
|
||||
# usually runs from inside `omarchy update`, and starting the notifier here would
|
||||
# pop a toast for the migrations running right after it -- the exact behavior
|
||||
# being removed. `systemctl enable` also needs a live user manager, which
|
||||
# `omarchy update` over SSH does not have, so fall back to writing precisely the
|
||||
# symlink it would have written rather than silently doing nothing.
|
||||
if ! systemctl --user enable omarchy-migrate-notify.service >/dev/null 2>&1; then
|
||||
mkdir -p "$wants_dir"
|
||||
ln -sfn /usr/lib/systemd/user/omarchy-migrate-notify.service \
|
||||
"$wants_dir/omarchy-migrate-notify.service"
|
||||
fi
|
||||
|
||||
# Drop the retired enablement by hand instead of through `systemctl disable`.
|
||||
# The package ships omarchy-update-user-notify.service as a compatibility
|
||||
# symlink onto the new unit, for users who have not reached this migration yet,
|
||||
# so disabling that name here would disable the replacement along with it.
|
||||
rm -f "$wants_dir/omarchy-update-user-notify.path" \
|
||||
"$wants_dir/omarchy-update-user-notify.service"
|
||||
|
||||
systemctl --user reset-failed omarchy-update-user-notify.path >/dev/null 2>&1 || true
|
||||
systemctl --user daemon-reload >/dev/null 2>&1 || true
|
||||
Reference in New Issue
Block a user