Hand browser and web app launches to the running browser directly (#13530)
* Hand browser and web app launches to the running browser directly With a Chromium-based browser already running, each launch started a second browser process only to pass its command line over the profile's singleton socket and exit, ~165ms before the running browser even heard of it. omarchy-cmd-browser-handoff sends that message itself with socat and waits for the ACK, so a web app opens in ~210ms instead of ~430ms. It hands off only what it can do exactly as the browser would: the packaged browser binary rather than a wrapper, a flags file holding nothing beyond the process flags Omarchy ships, no other data directory, and a socket we own. Anything else, or no answer, launches the browser as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Hand Brave Origin launches to the running browser too /usr/bin/brave-origin is the package's own launcher, reading brave-origin-flags.conf, with the profile in BraveSoftware/Brave-Origin. A web app now opens in ~158ms instead of ~345ms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
de63134b88
commit
97a9fce54f
5 files changed
+159
-4
No files matched your search
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Hand a command line to the running Chromium-based browser
|
||||
# omarchy:args=<browser-command> [browser-args...]
|
||||
# omarchy:hidden=true
|
||||
|
||||
# A second browser process spends ~165ms starting up only to pass its command
|
||||
# line to the running one over the profile's singleton socket, then exits. Send
|
||||
# it there directly, and fail when no browser acknowledges it so the caller can
|
||||
# launch one instead.
|
||||
config="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||
|
||||
# Only the browsers themselves: a wrapper in their place may pick a profile or
|
||||
# add flags of its own, which only running it can honour.
|
||||
case $(type -P "$1") in
|
||||
/usr/bin/chromium) profile=chromium flags=chromium-flags.conf ;;
|
||||
/usr/bin/google-chrome-stable) profile=google-chrome flags=chrome-flags.conf ;;
|
||||
/usr/bin/brave) profile=BraveSoftware/Brave-Browser flags=brave-flags.conf ;;
|
||||
/usr/bin/brave-origin) profile=BraveSoftware/Brave-Origin flags=brave-origin-flags.conf ;;
|
||||
/usr/bin/microsoft-edge-stable) profile=microsoft-edge flags=microsoft-edge-stable-flags.conf ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
|
||||
# The running browser already has the process flags Omarchy ships in the flags
|
||||
# file. Any other flag there may be meant for each launch, and a data directory
|
||||
# from the environment is another browser, so leave those to the launcher.
|
||||
if [[ -n ${CHROME_USER_DATA_DIR:-}${CHROME_CONFIG_HOME:-} ]] ||
|
||||
cat "/etc/$flags" "$config/$flags" 2>/dev/null | sed 's/#.*//' | tr -s '[:space:]' '\n' |
|
||||
grep -vE '^(--(ozone-platform|ozone-platform-hint|password-store|enable-features|load-extension)=.*)?$' | grep -q .; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for arg in "$@"; do
|
||||
[[ $arg == --user-data-dir* ]] && exit 1
|
||||
done
|
||||
|
||||
# The socket lives in a /tmp dir, which another user could recreate once a
|
||||
# crashed browser's is cleaned away, so only a socket of our own gets the URL.
|
||||
socket="$config/$profile/SingletonSocket"
|
||||
[[ -S $socket && -O $socket ]] || exit 1
|
||||
|
||||
reply=$({
|
||||
printf 'START\0%s\0browser' "$PWD"
|
||||
printf '\0%s' "$@"
|
||||
} | socat -t2 - "UNIX-CONNECT:$socket" 2>/dev/null)
|
||||
|
||||
[[ $reply == "ACK" ]]
|
||||
@@ -14,9 +14,11 @@ else
|
||||
private_flag="--incognito"
|
||||
fi
|
||||
|
||||
systemd-run --user --quiet --collect --unit="omarchy-browser-$(date +%s%N)" \
|
||||
--property=StandardOutput=null --property=StandardError=null \
|
||||
uwsm-app -- "$browser_exec" "${@/--private/$private_flag}"
|
||||
if ! omarchy-cmd-browser-handoff "$browser_exec" "${@/--private/$private_flag}"; then
|
||||
systemd-run --user --quiet --collect --unit="omarchy-browser-$(date +%s%N)" \
|
||||
--property=StandardOutput=null --property=StandardError=null \
|
||||
uwsm-app -- "$browser_exec" "${@/--private/$private_flag}"
|
||||
fi
|
||||
|
||||
url=""
|
||||
for argument in "$@"; do
|
||||
|
||||
@@ -10,4 +10,8 @@ google-chrome* | brave* | microsoft-edge* | opera* | vivaldi* | helium*) ;;
|
||||
*) browser="chromium.desktop" ;;
|
||||
esac
|
||||
|
||||
exec setsid uwsm-app -- $(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1) --app="$1" "${@:2}"
|
||||
browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$browser 2>/dev/null | head -1)
|
||||
|
||||
if ! omarchy-cmd-browser-handoff "$browser_exec" --app="$1" "${@:2}"; then
|
||||
exec setsid uwsm-app -- $browser_exec --app="$1" "${@:2}"
|
||||
fi
|
||||
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
require_command python3
|
||||
require_command socat
|
||||
|
||||
# The handoff only stands in for the packaged browser itself.
|
||||
if [[ $(type -P chromium) != "/usr/bin/chromium" ]]; then
|
||||
skip "browser handoff needs /usr/bin/chromium"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
export XDG_CONFIG_HOME="$test_tmp/config"
|
||||
socket="$XDG_CONFIG_HOME/chromium/SingletonSocket"
|
||||
received="$test_tmp/received"
|
||||
mkdir -p "${socket%/*}"
|
||||
flags_file="$XDG_CONFIG_HOME/chromium-flags.conf"
|
||||
cp "$ROOT/config/chromium-flags.conf" "$flags_file"
|
||||
echo "# A comment of the user's" >>"$flags_file"
|
||||
|
||||
# A running browser's side of the singleton socket: take each command line and
|
||||
# acknowledge it, as Chromium does.
|
||||
python3 - "$socket" "$received" <<'PY' &
|
||||
import socket, sys
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
server.bind(sys.argv[1])
|
||||
server.listen(1)
|
||||
while True:
|
||||
connection, _ = server.accept()
|
||||
message = b""
|
||||
while chunk := connection.recv(4096):
|
||||
message += chunk
|
||||
open(sys.argv[2], "wb").write(message)
|
||||
connection.sendall(b"ACK")
|
||||
connection.close()
|
||||
PY
|
||||
server=$!
|
||||
trap 'kill "$server" 2>/dev/null || true; rm -rf "$test_tmp"' EXIT
|
||||
|
||||
for _ in $(seq 100); do
|
||||
[[ -S $socket ]] && break
|
||||
sleep 0.02
|
||||
done
|
||||
|
||||
(cd "$test_tmp" && "$ROOT/bin/omarchy-cmd-browser-handoff" chromium --app="https://example.test/a b") ||
|
||||
fail "the running browser acknowledges a handed off command line"
|
||||
|
||||
expected=$(printf 'START\0%s\0browser\0--app=https://example.test/a b' "$test_tmp" | od -c)
|
||||
[[ $(od -c <"$received") == "$expected" ]] ||
|
||||
fail "the handoff sends the working directory and arguments as Chromium's singleton expects" "$(od -c <"$received")"
|
||||
pass "a command line is handed to the running browser over its singleton socket"
|
||||
|
||||
! "$ROOT/bin/omarchy-cmd-browser-handoff" chromium --user-data-dir=/elsewhere https://example.test ||
|
||||
fail "another data directory is left to a browser of its own"
|
||||
mkdir -p "$test_tmp/wrapper"
|
||||
printf '#!/bin/bash\nexec /usr/bin/chromium --profile-directory=Work "$@"\n' >"$test_tmp/wrapper/chromium"
|
||||
chmod +x "$test_tmp/wrapper/chromium"
|
||||
! PATH="$test_tmp/wrapper:$PATH" "$ROOT/bin/omarchy-cmd-browser-handoff" chromium https://example.test ||
|
||||
fail "a wrapper standing in for the browser is left to run"
|
||||
! CHROME_USER_DATA_DIR=/elsewhere "$ROOT/bin/omarchy-cmd-browser-handoff" chromium https://example.test ||
|
||||
fail "a data directory from the environment is left to a browser of its own"
|
||||
|
||||
# The handoff forwards no flags file, so any flag beyond Omarchy's own, which
|
||||
# may be meant for each launch, needs the launcher.
|
||||
for flag in '--new-window' '--enable-features=A --profile-directory="Profile 1"'; do
|
||||
cp "$ROOT/config/chromium-flags.conf" "$flags_file"
|
||||
echo "$flag" >>"$flags_file"
|
||||
! "$ROOT/bin/omarchy-cmd-browser-handoff" chromium https://example.test ||
|
||||
fail "a flags file with $flag is left to the launcher"
|
||||
done
|
||||
|
||||
# The browser is gone but its socket file is left, as after a crash.
|
||||
kill "$server"
|
||||
wait "$server" 2>/dev/null || true
|
||||
! "$ROOT/bin/omarchy-cmd-browser-handoff" chromium --app=https://example.test ||
|
||||
fail "a socket no browser answers on fails the handoff"
|
||||
! "$ROOT/bin/omarchy-cmd-browser-handoff" firefox https://example.test ||
|
||||
fail "a browser without a singleton socket fails the handoff"
|
||||
pass "the handoff fails when no Chromium-based browser answers, so the caller launches one"
|
||||
@@ -10,6 +10,9 @@ trap 'rm -rf "$test_tmp"' EXIT
|
||||
mock_bin="$test_tmp/bin"
|
||||
test_home="$test_tmp/home"
|
||||
mkdir -p "$mock_bin" "$test_home/.local/share/applications"
|
||||
# Keep the launcher away from the running browser's singleton socket, which it
|
||||
# would otherwise hand these test URLs to.
|
||||
export XDG_CONFIG_HOME="$test_home/.config" XDG_DATA_HOME="$test_home/.local/share"
|
||||
|
||||
cat >"$test_home/.local/share/applications/chromium.desktop" <<'EOF'
|
||||
[Desktop Entry]
|
||||
@@ -79,3 +82,16 @@ grep -Fx '^chromium.*$' "$focus_log" >/dev/null ||
|
||||
fail "browser launcher focuses the browser resolved from the HTTPS handler"
|
||||
|
||||
pass "browser launcher follows opened links to the browser workspace"
|
||||
|
||||
rm -f "$launch_log"
|
||||
cat >"$mock_bin/omarchy-cmd-browser-handoff" <<'SH'
|
||||
#!/bin/bash
|
||||
[[ $1 == "chromium" && $2 == "https://example.test/running" ]]
|
||||
SH
|
||||
chmod +x "$mock_bin/omarchy-cmd-browser-handoff"
|
||||
|
||||
HOME="$test_home" PATH="$mock_bin:$PATH" OMARCHY_TEST_BROWSER_LAUNCH="$launch_log" \
|
||||
OMARCHY_TEST_BROWSER_FOCUS="$focus_log" bash "$ROOT/bin/omarchy-launch-browser" "https://example.test/running"
|
||||
|
||||
[[ ! -e $launch_log ]] || fail "browser launcher starts no browser when the running one takes the URL"
|
||||
pass "browser launcher hands a URL to the running browser"
|
||||
Reference in new issue
Block a user