Files
omarchy/bin/omarchy-theme-set-browser
T
fd961e5300 Speed up the theme switch's browser refresh (#13038)
* Speed up theme switch by backgrounding preload and parallelizing browser refresh

`omarchy theme set` was blocking on `omarchy-theme-switcher --preload` (~1.1s)
and serially refreshing every Chromium-family browser (~1.0-1.5s), making a
picked theme feel slow even though the shell recolored instantly.

- Background `omarchy-theme-switcher --preload` like the background cache
- In `omarchy-theme-set-browser`, skip the privileged policy write and browser
  refreshes when every existing `color.json` already has the requested color
- Refresh only running browsers, and run those refreshes in parallel

Fixes #12627.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Harden the unchanged-color shortcut in omarchy-theme-set-browser

Review feedback identified that the original shortcut could vacuously skip
when no managed policy directories existed, and that it accepted a color.json
whose ownership or contents the privileged writer would have rewritten.

- Only skip when at least one managed directory exists and every existing
  color.json is a regular, root-owned 0644 file containing the canonical JSON
- Add OMARCHY_BROWSER_POLICY_DIRS as a test-only override so the setter's
  unchanged-color check does not depend on the host's real /etc policy files
- Update browser-policy-sudoers-test.sh to use that override, and make
  theme-set-browser-test.sh behavioral rather than grep-only

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Find running browsers with one process scan during the policy write

Each browser check ran its own pgrep, and every pgrep rescans /proc,
~40ms apiece. Read the process table once with ps while the policy
writer runs, keeping its stdin so a terminal sudo prompt stays in the
terminal, then refresh the running browsers in parallel.

Chrome's fallback to plain google-chrome never ran: the refresh helper
returned success for a missing browser, so the || branch was dead. Pick
whichever Chrome binary exists up front instead.

The unchanged-color shortcut keeps its root:root 0644 check without the
fallback for hosts lacking stat -c, which Omarchy never runs on. Its
tests stub stat, ps and command discovery, so they neither depend on
nor touch the host's browsers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:24:04 +02:00

95 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Apply the current theme color to Chromium, Chrome, Edge, and Brave
# omarchy:hidden=true
source "$OMARCHY_PATH/install/helpers/browser-policy.sh"
CHROMIUM_THEME=$HOME/.local/state/omarchy/current/theme/chromium.theme
THEME_HEX_COLOR=$BROWSER_POLICY_DEFAULT_COLOR
if [[ -f $CHROMIUM_THEME ]]; then
THEME_HEX_COLOR=$(browser_policy_theme_hex "$(<$CHROMIUM_THEME)")
fi
# Tests override this with a temporary directory list; production uses the
# fixed trust-root set from browser-policy.sh.
POLICY_DIRS=("${BROWSER_POLICY_MANAGED_DIRS[@]}")
if [[ -n ${OMARCHY_BROWSER_POLICY_DIRS:-} ]]; then
POLICY_DIRS=()
while IFS= read -r dir; do
POLICY_DIRS+=("$dir")
done <<< "$OMARCHY_BROWSER_POLICY_DIRS"
fi
# A managed color.json is already correct only when it is a regular, root-owned
# file with mode 0644 containing exactly the canonical JSON for the requested
# color.
file_is_canonical() {
local file=$1
[[ -f $file && ! -L $file ]] || return 1
[[ $(<"$file") == "$expected_json" ]] || return 1
[[ $(stat -c '%U:%G %a' "$file") == "root:root 644" ]]
}
# Skip the privileged policy write and browser refreshes entirely when every
# existing managed color.json is already canonical. The writer only touches
# directories that exist, so a browser installed since then has no color.json
# yet and takes the write.
expected_json='{"BrowserThemeColor": "'$THEME_HEX_COLOR'", "BrowserColorScheme": "device"}'
saw_any=false
all_unchanged=true
for dir in "${POLICY_DIRS[@]}"; do
[[ -d $dir && ! -L $dir ]] || continue
saw_any=true
if ! file_is_canonical "$dir/color.json"; then
all_unchanged=false
break
fi
done
$saw_any && $all_unchanged && exit 0
failed=0
# A script's background job reads /dev/null unless told otherwise, which would
# turn the writer's terminal sudo prompt into a pkexec dialog. Keep stdin.
omarchy-theme-set-browser-policy "${THEME_HEX_COLOR#\#}" <&0 &
policy_pid=$!
# While the policy writes, find the running browsers with one process table
# read. A pgrep per browser rescans /proc each time, ~40ms apiece.
declare -A running_names=()
running_args=""
while read -r name args; do
running_names[$name]=1
running_args+="$args"$'\n'
done < <(ps -eo comm=,args=)
# Chrome installs as either binary name, so take whichever exists.
chrome=google-chrome-stable
omarchy-cmd-present "$chrome" || chrome=google-chrome
browsers_to_refresh=()
for browser in chromium:chromium "chrome:$chrome" msedge:microsoft-edge-stable brave:brave; do
[[ -n ${running_names[${browser%%:*}]:-} ]] && omarchy-cmd-present "${browser#*:}" && browsers_to_refresh+=("${browser#*:}")
done
# Match on the binary path: the running process is named plain "brave", and a
# bare brave-origin pattern would also match the installer's own terminal.
[[ $running_args == *"/opt/brave-origin-bin/"* ]] && omarchy-cmd-present brave-origin && browsers_to_refresh+=(brave-origin)
wait "$policy_pid" || failed=1
# Refresh each running browser in parallel, so one slow launch doesn't
# serialize the rest.
refresh_pids=()
for command in "${browsers_to_refresh[@]}"; do
"$command" --refresh-platform-policy --no-startup-window &>/dev/null &
refresh_pids+=("$!")
done
for pid in "${refresh_pids[@]}"; do
wait "$pid"
done
exit "$failed"