Read the default browser from mimeapps.list when launching (#13520)
* Read the default browser from mimeapps.list when launching omarchy-launch-browser and omarchy-launch-webapp asked xdg-settings for the default browser on every launch, ~72ms through several POSIX shell scripts. The new omarchy-cmd-default-browser reads the http handler from the config-dir mimeapps.list files the way xdg-mime does, desktop-specific list first, taking the first listed entry whose command is installed, in ~10ms. With nothing set there it falls back to xdg-settings as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Let the first copy of a browser entry decide whether it is installed A user-local entry whose browser is gone could be rescued by a system copy of the same ID, which the launchers never read. xdg-mime judges the first copy found, as the launchers use it, so do the same. 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
8273b6c2d7
commit
fa729f139c
4 files changed
+132
-7
No files matched your search
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Print the desktop entry ID of the default web browser
|
||||
# omarchy:hidden=true
|
||||
|
||||
# Read the http handler from the config-dir mimeapps.list files the way xdg-mime
|
||||
# does, desktop-specific list first, taking the first listed entry that is
|
||||
# installed. xdg-settings reaches the same answer through several shell scripts
|
||||
# in ~70ms, which every browser and web app launch would otherwise pay.
|
||||
IFS=: read -ra data_dirs <<<"${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
|
||||
IFS=: read -ra config_dirs <<<"${XDG_CONFIG_HOME:-$HOME/.config}:${XDG_CONFIG_DIRS:-/etc/xdg}"
|
||||
IFS=: read -ra desktops <<<"${XDG_CURRENT_DESKTOP:-}"
|
||||
|
||||
# Installed means the command of the entry the launchers will read, the first
|
||||
# one found, still resolves: an entry of Omarchy's own can outlive the browser
|
||||
# it launched.
|
||||
installed() {
|
||||
local data_dir command
|
||||
|
||||
for data_dir in "${data_dirs[@]}"; do
|
||||
[[ -r $data_dir/applications/$1 ]] || continue
|
||||
command=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' "$data_dir/applications/$1" | head -1)
|
||||
[[ -n $command ]] && command -v "$command" >/dev/null
|
||||
return
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
for config_dir in "${config_dirs[@]}"; do
|
||||
for desktop in "${desktops[@]}" ""; do
|
||||
list="$config_dir/${desktop:+${desktop,,}-}mimeapps.list"
|
||||
[[ -f $list ]] || continue
|
||||
|
||||
entries=$(awk '
|
||||
/^\[Default Applications\]/ { section = 1; next }
|
||||
/^\[/ { section = 0 }
|
||||
section && index($0, "x-scheme-handler/http=") == 1 { print substr($0, 23); exit }
|
||||
' "$list")
|
||||
|
||||
IFS=';' read -ra entries <<<"$entries"
|
||||
for entry in "${entries[@]}"; do
|
||||
if [[ -n $entry ]] && installed "$entry"; then
|
||||
echo "$entry"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
# Nothing set in a config dir: let xdg-settings search the data dirs and caches.
|
||||
# It consults $BROWSER too, which the session points back at omarchy-launch-browser.
|
||||
browser=$(env -u BROWSER xdg-settings get default-web-browser 2>/dev/null)
|
||||
if [[ -z $browser ]]; then
|
||||
browser=$(xdg-mime query default x-scheme-handler/https 2>/dev/null)
|
||||
fi
|
||||
|
||||
[[ -n $browser ]] && echo "$browser"
|
||||
@@ -3,10 +3,7 @@
|
||||
# omarchy:summary=Launch the default browser as determined by xdg-settings.
|
||||
# omarchy:args=[url]
|
||||
|
||||
default_browser=$(env -u BROWSER xdg-settings get default-web-browser)
|
||||
if [[ -z $default_browser ]]; then
|
||||
default_browser=$(xdg-mime query default x-scheme-handler/https)
|
||||
fi
|
||||
default_browser=$(omarchy-cmd-default-browser)
|
||||
browser_exec=$(sed -n 's/^Exec=\([^ ]*\).*/\1/p' {~/.local,~/.nix-profile,/usr}/share/applications/$default_browser 2>/dev/null | head -1)
|
||||
|
||||
if $browser_exec --help 2>/dev/null | grep -q MOZ_LOG; then
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
# omarchy:summary=Launch a URL as a web app in the default supported browser
|
||||
# omarchy:args=<url>
|
||||
|
||||
# The session sets BROWSER to omarchy-launch-browser, which sends xdg-settings
|
||||
# down a slower path (~100ms against ~30ms) to the same answer.
|
||||
browser=$(env -u BROWSER xdg-settings get default-web-browser)
|
||||
browser=$(omarchy-cmd-default-browser)
|
||||
|
||||
case $browser in
|
||||
google-chrome* | brave* | microsoft-edge* | opera* | vivaldi* | helium*) ;;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
mock_bin="$test_tmp/bin"
|
||||
mkdir -p "$mock_bin" "$test_tmp/config" "$test_tmp/data/applications" "$test_tmp/system/applications"
|
||||
|
||||
export HOME="$test_tmp/home"
|
||||
export XDG_CONFIG_HOME="$test_tmp/config"
|
||||
export XDG_CONFIG_DIRS="$test_tmp/etc"
|
||||
export XDG_DATA_HOME="$test_tmp/data"
|
||||
export XDG_DATA_DIRS="$test_tmp/system"
|
||||
export XDG_CURRENT_DESKTOP=Hyprland
|
||||
export BROWSER=omarchy-launch-browser
|
||||
export OMARCHY_TEST_XDG_SETTINGS_LOG="$test_tmp/xdg-settings"
|
||||
|
||||
cat >"$mock_bin/xdg-settings" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\n' "${BROWSER:-unset}" >"$OMARCHY_TEST_XDG_SETTINGS_LOG"
|
||||
echo fallback.desktop
|
||||
SH
|
||||
export PATH="$mock_bin:$ROOT/bin:$PATH"
|
||||
|
||||
for browser in chromium firefox brave; do
|
||||
printf '#!/bin/bash\n' >"$mock_bin/$browser"
|
||||
done
|
||||
chmod +x "$mock_bin"/*
|
||||
|
||||
echo "Exec=chromium %U" >"$XDG_DATA_HOME/applications/chromium.desktop"
|
||||
echo "Exec=firefox %u" >"$XDG_DATA_HOME/applications/firefox.desktop"
|
||||
echo "Exec=brave %U" >"$XDG_DATA_DIRS/applications/brave-browser.desktop"
|
||||
# An entry of Omarchy's own left behind by a browser since removed, shadowing
|
||||
# a system copy that the launchers would never read.
|
||||
echo "Exec=removed-browser %U" >"$XDG_DATA_HOME/applications/removed.desktop"
|
||||
echo "Exec=brave %U" >"$XDG_DATA_DIRS/applications/removed.desktop"
|
||||
|
||||
cat >"$XDG_CONFIG_HOME/mimeapps.list" <<'EOF'
|
||||
[Added Associations]
|
||||
x-scheme-handler/http=firefox.desktop;
|
||||
|
||||
[Default Applications]
|
||||
text/html=firefox.desktop
|
||||
x-scheme-handler/http=missing.desktop;removed.desktop;chromium.desktop;
|
||||
EOF
|
||||
|
||||
[[ $(omarchy-cmd-default-browser) == "chromium.desktop" ]] ||
|
||||
fail "default browser is the first installed http handler in mimeapps.list"
|
||||
[[ ! -e $OMARCHY_TEST_XDG_SETTINGS_LOG ]] ||
|
||||
fail "default browser skips xdg-settings when mimeapps.list names one"
|
||||
|
||||
cat >"$XDG_CONFIG_HOME/hyprland-mimeapps.list" <<'EOF'
|
||||
[Default Applications]
|
||||
x-scheme-handler/http=brave-browser.desktop
|
||||
EOF
|
||||
|
||||
[[ $(omarchy-cmd-default-browser) == "brave-browser.desktop" ]] ||
|
||||
fail "default browser prefers the desktop-specific mimeapps.list"
|
||||
|
||||
rm "$XDG_CONFIG_HOME/hyprland-mimeapps.list"
|
||||
printf '[Default Applications]\nx-scheme-handler/http=missing.desktop\n' >"$XDG_CONFIG_HOME/mimeapps.list"
|
||||
|
||||
[[ $(omarchy-cmd-default-browser) == "fallback.desktop" ]] ||
|
||||
fail "default browser falls back to xdg-settings when no listed handler is installed"
|
||||
[[ $(<"$OMARCHY_TEST_XDG_SETTINGS_LOG") == "unset" ]] ||
|
||||
fail "default browser unsets BROWSER before asking xdg-settings"
|
||||
|
||||
pass "default browser reads mimeapps.list and falls back to xdg-settings"
|
||||
Reference in new issue
Block a user