diff --git a/scripts/xdg-utils-common.in b/scripts/xdg-utils-common.in index f920799..ad66b29 100644 --- a/scripts/xdg-utils-common.in +++ b/scripts/xdg-utils-common.in @@ -20,11 +20,16 @@ first_word() #------------------------------------------------------------- # map a binary to a .desktop file +# Search every desktop file in standard locations, and if one contains any +# Exec line whose target (after resolving symlinks) is the same as the given +# parameter file (after resolving symlinks), then print the name of that +# desktop file. This only emits the first desktop file found. Luckily, wildcard +# expansion is ordered, so the lexically-first filename of a match is returned. binary_to_desktop_file() { search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" - binary="`which "$1"`" - binary="`readlink -f "$binary"`" + binary=$(which "$1") + binary=$(readlink -f "$binary") base="`basename "$binary"`" IFS=: for dir in $search; do @@ -37,13 +42,17 @@ binary_to_desktop_file() grep -q "^Exec.*$base" "$file" || continue # Make sure it's a visible desktop file (e.g. not "preferred-web-browser.desktop"). grep -Eq "^(NoDisplay|Hidden)=true" "$file" && continue - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" - command="`which "$command"`" - if [ x"`readlink -f "$command"`" = x"$binary" ]; then - # Fix any double slashes that got added path composition - echo "$file" | sed -e 's,//*,/,g' - return - fi + + # "TryExec" isn't good enough. Only "Exec". Test every Exec in the file. Only use one. + grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | \ + while read command argumentlist; do + command_full_path=$(which "$command") + if [ $(readlink -f "$command_full_path") = "$binary" ]; then + # Fix any double slashes that got added path composition + echo "$file" | sed -e 's,//*,/,g' + return # That was out answer. Nothing else to do. + fi + done done done } @@ -54,7 +63,7 @@ binary_to_desktop_file() desktop_file_to_binary() { search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" - desktop="`basename "$1"`" + desktop=$(basename "$1") IFS=: for dir in $search; do unset IFS @@ -62,10 +71,13 @@ desktop_file_to_binary() file="$dir/applications/$desktop" [ -r "$file" ] || continue # Remove any arguments (%F, %f, %U, %u, etc.). - command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | first_word`" - command="`which "$command"`" - readlink -f "$command" - return + grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | \ + while read command argumentlist; do + # Use while-read to process one line, not all lines. + command_full_path=$(which "$command") + readlink -f "$command_full_path" + return # Don't continue after the first. + done done }