Spaces:
Running
Running
#!/bin/sh | |
#--------------------------------------------- | |
# xdg-settings | |
# | |
# Utility script to get various settings from the desktop environment. | |
# | |
# Refer to the usage() function below for usage. | |
# | |
# Copyright 2009, Google Inc. | |
# | |
# LICENSE: | |
# | |
# Permission is hereby granted, free of charge, to any person obtaining a | |
# copy of this software and associated documentation files (the "Software"), | |
# to deal in the Software without restriction, including without limitation | |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
# and/or sell copies of the Software, and to permit persons to whom the | |
# Software is furnished to do so, subject to the following conditions: | |
# | |
# The above copyright notice and this permission notice shall be included | |
# in all copies or substantial portions of the Software. | |
# | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
# OTHER DEALINGS IN THE SOFTWARE. | |
# | |
#--------------------------------------------- | |
manualpage() | |
{ | |
cat << _MANUALPAGE | |
Name | |
xdg-settings - get various settings from the desktop environment | |
Synopsis | |
xdg-settings { get | check | set } {property} [subproperty] [value] | |
xdg-settings { --help | --list | --manual | --version } | |
Description | |
xdg-settings gets various settings from the desktop environment. For instance, | |
desktop environments often provide proxy configuration and default web browser | |
settings. Using xdg-settings these parameters can be extracted for use by | |
applications that do not use the desktop environment's libraries (which would | |
use the settings natively). | |
xdg-settings is for use inside a desktop session only. It is not recommended to | |
use xdg-settings as root. | |
Options | |
--help | |
Show command synopsis. | |
--list | |
List all properties xdg-settings knows about. | |
--manual | |
Show this manualpage. | |
--version | |
Show the xdg-utils version information. | |
Properties | |
When using xdg-settings to get, check or set a destkop setting, properties and | |
possibly sub-properties are used to specify the setting to be changed. | |
Some properties (such as default-web-browser) fully describe the setting to be | |
changed. Other properties (such as default-url-scheme-handler) require more | |
information (in this case the actual scheme to set the default handler for) | |
which must be provided in a sub-property. | |
Exit Codes | |
An exit code of 0 indicates success while a non-zero exit code indicates | |
failure. The following failure codes can be returned: | |
1 | |
Error in command line syntax. | |
2 | |
One of the files passed on the command line did not exist. | |
3 | |
A required tool could not be found. | |
4 | |
The action failed. | |
Examples | |
Get the desktop file name of the current default web browser | |
xdg-settings get default-web-browser | |
Check whether the default web browser is firefox.desktop, which can be false | |
even if "get default-web-browser" says that is the current value (if only some | |
of the underlying settings actually reflect that value) | |
xdg-settings check default-web-browser firefox.desktop | |
Set the default web browser to google-chrome.desktop | |
xdg-settings set default-web-browser google-chrome.desktop | |
Set the default mailto URL scheme handler to be evolution.desktop | |
xdg-settings set default-url-scheme-handler mailto evolution.desktop | |
_MANUALPAGE | |
} | |
usage() | |
{ | |
cat << _USAGE | |
xdg-settings - get various settings from the desktop environment | |
Synopsis | |
xdg-settings { get | check | set } {property} [subproperty] [value] | |
xdg-settings { --help | --list | --manual | --version } | |
_USAGE | |
} | |
#@xdg-utils-common@ | |
#---------------------------------------------------------------------------- | |
# Common utility functions included in all XDG wrapper scripts | |
#---------------------------------------------------------------------------- | |
DEBUG() | |
{ | |
[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; | |
[ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; | |
shift | |
echo "$@" >&2 | |
} | |
# This handles backslashes but not quote marks. | |
first_word() | |
{ | |
read first rest | |
echo "$first" | |
} | |
#------------------------------------------------------------- | |
# map a binary to a .desktop file | |
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"`" | |
base="`basename "$binary"`" | |
IFS=: | |
for dir in $search; do | |
unset IFS | |
[ "$dir" ] || continue | |
[ -d "$dir/applications" -o -d "$dir/applnk" ] || continue | |
for file in "$dir"/applications/*.desktop "$dir"/applications/*/*.desktop "$dir"/applnk/*.desktop "$dir"/applnk/*/*.desktop; do | |
[ -r "$file" ] || continue | |
# Check to make sure it's worth the processing. | |
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 | |
done | |
done | |
} | |
#------------------------------------------------------------- | |
# map a .desktop file to a binary | |
## FIXME: handle vendor dir case | |
desktop_file_to_binary() | |
{ | |
search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" | |
desktop="`basename "$1"`" | |
IFS=: | |
for dir in $search; do | |
unset IFS | |
[ "$dir" -a -d "$dir/applications" ] || continue | |
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 | |
done | |
} | |
#------------------------------------------------------------- | |
# Exit script on successfully completing the desired operation | |
exit_success() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "$@" | |
echo | |
fi | |
exit 0 | |
} | |
#----------------------------------------- | |
# Exit script on malformed arguments, not enough arguments | |
# or missing required option. | |
# prints usage information | |
exit_failure_syntax() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
echo "Try 'xdg-settings --help' for more information." >&2 | |
else | |
usage | |
echo "Use 'man xdg-settings' or 'xdg-settings --manual' for additional info." | |
fi | |
exit 1 | |
} | |
#------------------------------------------------------------- | |
# Exit script on missing file specified on command line | |
exit_failure_file_missing() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
fi | |
exit 2 | |
} | |
#------------------------------------------------------------- | |
# Exit script on failure to locate necessary tool applications | |
exit_failure_operation_impossible() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
fi | |
exit 3 | |
} | |
#------------------------------------------------------------- | |
# Exit script on failure returned by a tool application | |
exit_failure_operation_failed() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
fi | |
exit 4 | |
} | |
#------------------------------------------------------------ | |
# Exit script on insufficient permission to read a specified file | |
exit_failure_file_permission_read() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
fi | |
exit 5 | |
} | |
#------------------------------------------------------------ | |
# Exit script on insufficient permission to write a specified file | |
exit_failure_file_permission_write() | |
{ | |
if [ $# -gt 0 ]; then | |
echo "xdg-settings: $@" >&2 | |
fi | |
exit 6 | |
} | |
check_input_file() | |
{ | |
if [ ! -e "$1" ]; then | |
exit_failure_file_missing "file '$1' does not exist" | |
fi | |
if [ ! -r "$1" ]; then | |
exit_failure_file_permission_read "no permission to read file '$1'" | |
fi | |
} | |
check_vendor_prefix() | |
{ | |
file_label="$2" | |
[ -n "$file_label" ] || file_label="filename" | |
file=`basename "$1"` | |
case "$file" in | |
[a-zA-Z]*-*) | |
return | |
;; | |
esac | |
echo "xdg-settings: $file_label '$file' does not have a proper vendor prefix" >&2 | |
echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 | |
echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 | |
echo "Use --novendor to override or 'xdg-settings --manual' for additional info." >&2 | |
exit 1 | |
} | |
check_output_file() | |
{ | |
# if the file exists, check if it is writeable | |
# if it does not exists, check if we are allowed to write on the directory | |
if [ -e "$1" ]; then | |
if [ ! -w "$1" ]; then | |
exit_failure_file_permission_write "no permission to write to file '$1'" | |
fi | |
else | |
DIR=`dirname "$1"` | |
if [ ! -w "$DIR" -o ! -x "$DIR" ]; then | |
exit_failure_file_permission_write "no permission to create file '$1'" | |
fi | |
fi | |
} | |
#---------------------------------------- | |
# Checks for shared commands, e.g. --help | |
check_common_commands() | |
{ | |
while [ $# -gt 0 ] ; do | |
parm="$1" | |
shift | |
case "$parm" in | |
--help) | |
usage | |
echo "Use 'man xdg-settings' or 'xdg-settings --manual' for additional info." | |
exit_success | |
;; | |
--manual) | |
manualpage | |
exit_success | |
;; | |
--version) | |
echo "xdg-settings 1.1.0 rc1" | |
exit_success | |
;; | |
esac | |
done | |
} | |
check_common_commands "$@" | |
[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; | |
if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then | |
# Be silent | |
xdg_redirect_output=" > /dev/null 2> /dev/null" | |
else | |
# All output to stderr | |
xdg_redirect_output=" >&2" | |
fi | |
#-------------------------------------- | |
# Checks for known desktop environments | |
# set variable DE to the desktop environments name, lowercase | |
detectDE() | |
{ | |
# see https://bugs.freedesktop.org/show_bug.cgi?id=34164 | |
unset GREP_OPTIONS | |
if [ -n "${XDG_CURRENT_DESKTOP}" ]; then | |
case "${XDG_CURRENT_DESKTOP}" in | |
GNOME) | |
DE=gnome; | |
;; | |
KDE) | |
DE=kde; | |
;; | |
LXDE) | |
DE=lxde; | |
;; | |
XFCE) | |
DE=xfce | |
esac | |
fi | |
if [ x"$DE" = x"" ]; then | |
# classic fallbacks | |
if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; | |
elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; | |
elif `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner string:org.gnome.SessionManager > /dev/null 2>&1` ; then DE=gnome; | |
elif xprop -root _DT_SAVE_MODE 2> /dev/null | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; | |
elif xprop -root 2> /dev/null | grep -i '^xfce_desktop_window' >/dev/null 2>&1; then DE=xfce | |
fi | |
fi | |
if [ x"$DE" = x"" ]; then | |
# fallback to checking $DESKTOP_SESSION | |
case "$DESKTOP_SESSION" in | |
gnome) | |
DE=gnome; | |
;; | |
LXDE) | |
DE=lxde; | |
;; | |
xfce|xfce4) | |
DE=xfce; | |
;; | |
esac | |
fi | |
if [ x"$DE" = x"" ]; then | |
# fallback to uname output for other platforms | |
case "$(uname 2>/dev/null)" in | |
Darwin) | |
DE=darwin; | |
;; | |
esac | |
fi | |
if [ x"$DE" = x"gnome" ]; then | |
# gnome-default-applications-properties is only available in GNOME 2.x | |
# but not in GNOME 3.x | |
which gnome-default-applications-properties > /dev/null 2>&1 || DE="gnome3" | |
fi | |
} | |
#---------------------------------------------------------------------------- | |
# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 | |
# It also always returns 1 in KDE 3.4 and earlier | |
# Simply return 0 in such case | |
kfmclient_fix_exit_code() | |
{ | |
version=`LC_ALL=C.UTF-8 kde-config --version 2>/dev/null | grep '^KDE'` | |
major=`echo $version | sed 's/KDE.*: \([0-9]\).*/\1/'` | |
minor=`echo $version | sed 's/KDE.*: [0-9]*\.\([0-9]\).*/\1/'` | |
release=`echo $version | sed 's/KDE.*: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` | |
test "$major" -gt 3 && return $1 | |
test "$minor" -gt 5 && return $1 | |
test "$release" -gt 4 && return $1 | |
return 0 | |
} | |
check_desktop_filename() | |
{ | |
case "$1" in | |
*/*) | |
exit_failure_syntax "invalid application name" | |
;; | |
*.desktop) | |
return | |
;; | |
*) | |
exit_failure_syntax "invalid application name" | |
;; | |
esac | |
} | |
# {{{ default browser | |
# {{{ utility functions | |
# In order to remove an application from the automatically-generated list of | |
# applications for handling a given MIME type, the desktop environment may copy | |
# the global .desktop file into the user's .local directory, and remove that | |
# MIME type from its list. In that case, we must restore the MIME type to the | |
# application's list of MIME types before we can set it as the default for that | |
# MIME type. (We can't just delete the local version, since the user may have | |
# made other changes to it as well. So, tweak the existing file.) | |
# This function is hard-coded for text/html but it could be adapted if needed. | |
fix_local_desktop_file() | |
{ | |
if test -z "$2" ; then | |
MIME="text/html" | |
else | |
MIME="$2" | |
fi | |
apps="${XDG_DATA_HOME:-$HOME/.local/share}/applications" | |
# No local desktop file? | |
[ ! -f "$apps/$1" ] && return | |
MIMETYPES="`grep "^MimeType=" "$apps/$1" | cut -d= -f 2-`" | |
case "$MIMETYPES" in | |
$MIME\;*|*\;$MIME\;*|*\;$MIME\;|*\;$MIME) | |
# Already has the mime-type? Great! | |
return 0 | |
;; | |
esac | |
# Add the mime-type to the list | |
temp="`mktemp "$apps/$1.XXXXXX"`" || return | |
grep -v "^MimeType=" "$apps/$1" >> "$temp" | |
echo "MimeType=$MIME;$MIMETYPES" >> "$temp" | |
oldlines="`wc -l < "$apps/$1"`" | |
newlines="`wc -l < "$temp"`" | |
# The new file should have at least as many lines as the old. | |
if [ $oldlines -le $newlines ]; then | |
mv "$temp" "$apps/$1" | |
# This can take a little bit to get noticed. | |
sleep 4 | |
else | |
rm -f "$temp" | |
return 1 | |
fi | |
} | |
# }}} utility functions | |
# {{{ MIME utilities | |
xdg_mime_fixup() | |
{ | |
# xdg-mime may use ktradertest, which will fork off a copy of kdeinit if | |
# one does not already exist. It will exit after about 15 seconds if no | |
# further processes need it around. But since it does not close its stdout, | |
# the shell (via grep) will wait around for kdeinit to exit. If we start a | |
# copy here, that copy will be used in xdg-mime and we will avoid waiting. | |
if [ "$DE" = kde -a -z "$XDG_MIME_FIXED" ]; then | |
ktradertest text/html Application > /dev/null 2>&1 | |
# Only do this once, as we only need it once. | |
XDG_MIME_FIXED=yes | |
fi | |
} | |
get_browser_mime() | |
{ | |
if test -z "$1" ; then | |
MIME="text/html" | |
else | |
MIME="$1" | |
fi | |
xdg_mime_fixup | |
xdg-mime query default "$MIME" | |
} | |
set_browser_mime() | |
{ | |
xdg_mime_fixup | |
if test -z "$2" ; then | |
MIME="text/html" | |
else | |
MIME="$2" | |
fi | |
orig="`get_browser_mime $MIME`" | |
# Fixing the local desktop file can actually change the default browser all | |
# by itself, so we fix it only after querying to find the current default. | |
fix_local_desktop_file "$1" "$MIME" || return | |
mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/applications" | |
xdg-mime default "$1" "$MIME" || return | |
if [ x"`get_browser_mime`" != x"$1" ]; then | |
# Put back the original value | |
xdg-mime default "$orig" "$MIME" | |
exit_failure_operation_failed | |
fi | |
} | |
# }}} MIME utilities | |
# {{{ KDE utilities | |
# Reads the KDE configuration setting, compensating for a bug in some versions of kreadconfig. | |
read_kde_config() | |
{ | |
configfile="$1" | |
configsection="$2" | |
configkey="$3" | |
application="`kreadconfig --file $configfile --group $configsection --key $configkey`" | |
if [ x"$application" != x ]; then | |
echo "$application" | |
else | |
# kreadconfig in KDE 4 may not notice Key[$*]=... localized settings, so | |
# check by hand if it didn't find anything (oddly kwriteconfig works | |
# fine though). | |
configfile_dir=`kde${KDE_SESSION_VERSION}-config --path config | cut -d ':' -f 1` | |
configfile_path="$configfile_dir/$configfile" | |
[ ! -f "$configfile_path" ] && return | |
# This will only take the first value if there is more than one. | |
grep "^$configkey"'\[$[^]=]*\]=' "$configfile_path" | head -n 1 | cut -d= -f 2- | |
fi | |
} | |
# }}} KDE utilities | |
# {{{ KDE | |
# Resolves the KDE browser setting to a binary: if prefixed with !, simply removes it; | |
# otherwise, uses desktop_file_to_binary to get the binary out of the desktop file. | |
resolve_kde_browser() | |
{ | |
[ -z "$browser" ] && return | |
case "$browser" in | |
!*) | |
echo "${browser#!}" | |
;; | |
*) | |
desktop_file_to_binary "$browser" | |
;; | |
esac | |
} | |
# Does the opposite of resolve_kde_browser: if prefixed with !, tries to find a desktop | |
# file corresponding to the binary, otherwise just returns the desktop file name. | |
resolve_kde_browser_desktop() | |
{ | |
[ -z "$browser" ] && return | |
case "$browser" in | |
!*) | |
desktop="`binary_to_desktop_file "${browser#!}"`" | |
basename "$desktop" | |
;; | |
*) | |
echo "$browser" | |
;; | |
esac | |
} | |
read_kde_browser() | |
{ | |
read_kde_config kdeglobals General BrowserApplication | |
} | |
get_browser_kde() | |
{ | |
browser="`read_kde_browser`" | |
if [ x"$browser" = x ]; then | |
# No explicit default browser; KDE will use the MIME type text/html. | |
get_browser_mime | |
else | |
resolve_kde_browser_desktop | |
fi | |
} | |
check_browser_kde() | |
{ | |
check="`desktop_file_to_binary "$1"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
browser="`read_kde_browser`" | |
binary="`resolve_kde_browser`" | |
# Because KDE will use the handler for MIME type text/html if this value | |
# is empty, we allow either the empty string or a match to $check here. | |
if [ x"$binary" != x -a x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
browser="`get_browser_mime`" | |
binary="`desktop_file_to_binary "$browser"`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
set_browser_kde() | |
{ | |
set_browser_mime "$1" || return | |
kwriteconfig --file kdeglobals --group General --key BrowserApplication "$1" | |
} | |
# }}} KDE | |
# {{{ GNOME | |
get_browser_gnome() | |
{ | |
binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec | first_word`" | |
if [ x"$binary" = x ]; then | |
# No default browser; GNOME might use the MIME type text/html. | |
get_browser_mime | |
else | |
# gconftool gives the binary (maybe with %s etc. afterward), | |
# but we want the desktop file name, not the binary. So, we | |
# have to find the desktop file to which it corresponds. | |
desktop="`binary_to_desktop_file "$binary"`" | |
basename "$desktop" | |
fi | |
} | |
check_browser_gnome() | |
{ | |
check="`desktop_file_to_binary "$1"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
binary="`gconftool-2 --get /desktop/gnome/applications/browser/exec | first_word`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
# Check HTTP and HTTPS, but not about: and unknown:. | |
for protocol in http https; do | |
binary="`gconftool-2 --get /desktop/gnome/url-handlers/$protocol/command | first_word`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
done | |
browser="`get_browser_mime`" | |
binary="`desktop_file_to_binary "$browser"`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
set_browser_gnome() | |
{ | |
binary="`desktop_file_to_binary "$1"`" | |
[ "$binary" ] || exit_failure_file_missing | |
set_browser_mime "$1" || return | |
# Set the default browser. | |
gconftool-2 --type string --set /desktop/gnome/applications/browser/exec "$binary" | |
gconftool-2 --type bool --set /desktop/gnome/applications/browser/needs_term false | |
gconftool-2 --type bool --set /desktop/gnome/applications/browser/nremote true | |
# Set the handler for HTTP and HTTPS. | |
for protocol in http https; do | |
gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s" | |
gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/needs_terminal false | |
gconftool-2 --type bool --set /desktop/gnome/url-handlers/$protocol/enabled true | |
done | |
# Set the handler for about: and unknown URL types. | |
for protocol in about unknown; do | |
gconftool-2 --type string --set /desktop/gnome/url-handlers/$protocol/command "$binary %s" | |
done | |
} | |
# }}} GNOME | |
# {{{ GNOME 3.x | |
get_browser_gnome3() | |
{ | |
get_browser_mime "x-scheme-handler/http" | |
} | |
check_browser_gnome3() | |
{ | |
desktop="$1" | |
check="`desktop_file_to_binary "$1"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
# Check HTTP and HTTPS, but not about: and unknown:. | |
for protocol in http https; do | |
browser="`get_browser_mime "x-scheme-handler/$protocol"`" | |
if [ x"$browser" != x"$desktop" ]; then | |
echo no | |
exit_success | |
fi | |
done | |
echo yes | |
exit_success | |
} | |
set_browser_gnome3() | |
{ | |
binary="`desktop_file_to_binary "$1"`" | |
[ "$binary" ] || exit_failure_file_missing | |
set_browser_mime "$1" || return | |
# Set the default browser. | |
for protocol in http https about unknown; do | |
set_browser_mime "$1" "x-scheme-handler/$protocol" || return | |
done | |
} | |
# }}} GNOME 3.x | |
# {{{ xfce | |
get_browser_xfce() | |
{ | |
search="${XDG_CONFIG_HOME:-$HOME/.config}:${XDG_CONFIG_DIRS:-/etc/xdg}" | |
IFS=: | |
for dir in $search; do | |
unset IFS | |
[ "$dir" -a -d "$dir/xfce4" ] || continue | |
file="$dir/xfce4/helpers.rc" | |
[ -r "$file" ] || continue | |
grep -q "^WebBrowser=" "$file" || continue | |
desktop="`grep "^WebBrowser=" "$file" | cut -d= -f 2-`" | |
echo "$desktop.desktop" | |
return | |
done | |
exit_failure_operation_failed | |
} | |
check_browser_xfce() | |
{ | |
browser="`get_browser_xfce`" | |
if [ x"$browser" != x"$1" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
check_xfce_desktop_file() | |
{ | |
# Annoyingly, xfce wants its .desktop files in a separate directory instead | |
# of the standard locations, and requires a few custom tweaks to them: | |
# "Type" must be "X-XFCE-Helper" | |
# "X-XFCE-Category" must be "WebBrowser" (for web browsers, anyway) | |
# "X-XFCE-Commands" and "X-XFCE-CommandsWithParameter" must be set | |
search="${XDG_DATA_HOME:-$HOME/.local/share}:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" | |
IFS=: | |
for dir in $search; do | |
unset IFS | |
[ "$dir" -a -d "$dir/xfce4/helpers" ] || continue | |
file="$dir/xfce4/helpers/$1" | |
# We have the file, no need to create it. | |
[ -r "$file" ] && return | |
done | |
IFS=: | |
for dir in $search; do | |
unset IFS | |
[ "$dir" -a -d "$dir/applications" ] || continue | |
file="$dir/applications/$1" | |
if [ -r "$file" ]; then | |
# Found a file to convert. | |
target="${XDG_DATA_HOME:-$HOME/.local/share}/xfce4/helpers" | |
mkdir -p "$target" | |
grep -v "^Type=" "$file" > "$target/$1" | |
echo "Type=X-XFCE-Helper" >> "$target/$1" | |
echo "X-XFCE-Category=WebBrowser" >> "$target/$1" | |
# Change %F, %f, %U, and %u to "%s". | |
command="`grep -E "^Exec(\[[^]=]*])?=" "$file" | cut -d= -f 2- | sed -e 's/%[FfUu]/"%s"/g'`" | |
echo "X-XFCE-Commands=`echo "$command" | first_word`" >> "$target/$1" | |
echo "X-XFCE-CommandsWithParameter=$command" >> "$target/$1" | |
return | |
fi | |
done | |
return 1 | |
} | |
set_browser_xfce() | |
{ | |
check_xfce_desktop_file "$1" || exit_failure_operation_failed | |
helper_dir="${XDG_CONFIG_HOME:-$HOME/.config}/xfce4" | |
if [ ! -d "$helper_dir" ]; then | |
mkdir -p "$helper_dir" || exit_failure_operation_failed | |
fi | |
helpers_rc="$helper_dir/helpers.rc" | |
# Create the file if it does not exist to avoid special cases below. | |
if [ ! -r "$helpers_rc" ]; then | |
touch "$helpers_rc" || exit_failure_operation_failed | |
fi | |
temp="`mktemp "$helpers_rc.XXXXXX"`" || return | |
grep -v "^WebBrowser=" "$helpers_rc" >> "$temp" | |
echo "WebBrowser=${1%.desktop}" >> "$temp" | |
oldlines="`wc -l < "$helpers_rc"`" | |
newlines="`wc -l < "$temp"`" | |
# The new file should have at least as many lines as the old. | |
if [ $oldlines -le $newlines ]; then | |
mv "$temp" "$helpers_rc" | |
else | |
rm -f "$temp" | |
return 1 | |
fi | |
} | |
# }}} xfce | |
# }}} default browser | |
# {{{ default url scheme handler | |
exit_unimplemented_default_handler() | |
{ | |
exit_failure_operation_impossible "default-url-scheme-handler not implemented for $DE" | |
} | |
# {{{ KDE | |
# Recent versions of KDE support default scheme handler applications using the | |
# mime type of x-scheme-handler/scheme. Older versions will not support this | |
# but do have support for setting a default mail handler. There is also a | |
# system in KDE where .protocol files can be used, however this is not | |
# supported by this script. When reading a scheme handler we will use the | |
# default mail handler for the mailto scheme, otherwise we will use the mime | |
# type x-scheme-handler/scheme. | |
get_url_scheme_handler_kde() | |
{ | |
if [ "$1" = "mailto" ]; then | |
handler="`read_kde_config emaildefaults PROFILE_Default EmailClient | first_word`" | |
echo "handler is $handler" | |
if [ x"$handler" != x ]; then | |
binary_to_desktop_file "$handler" | |
else | |
get_browser_mime "x-scheme-handler/$1" | |
fi | |
else | |
get_browser_mime "x-scheme-handler/$1" | |
fi | |
} | |
check_url_scheme_handler_kde() | |
{ | |
check="`desktop_file_to_binary "$2"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
if [ x"$1" = "mailto" ]; then | |
binary="`read_kde_config emaildefaults PROFILE_Default EmailClient`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
fi | |
handler="`get_browser_mime x-scheme-handler/$1`" | |
binary="`desktop_file_to_binary "$handler"`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
set_url_scheme_handler_kde() | |
{ | |
set_browser_mime "$2" "x-scheme-handler/$1" || return | |
if [ "$1" = "mailto" ]; then | |
binary="`desktop_file_to_binary "$2"`" | |
kwriteconfig --file emaildefaults --group PROFILE_Default --key EmailClient "$binary" | |
fi | |
} | |
# }}} KDE | |
# {{{ GNOME | |
get_url_scheme_handler_gnome() | |
{ | |
binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`" | |
if [ x"$binary" != x"" ]; then | |
# gconftool gives the binary (maybe with %s etc. afterward), | |
# but we want the desktop file name, not the binary. So, we | |
# have to find the desktop file to which it corresponds. | |
desktop="`binary_to_desktop_file "$binary"`" | |
basename "$desktop" | |
fi | |
} | |
check_url_scheme_handler_gnome() | |
{ | |
check="`desktop_file_to_binary "$2"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
binary="`gconftool-2 --get /desktop/gnome/url-handlers/$1/command | first_word`" | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
set_url_scheme_handler_gnome() | |
{ | |
binary="`desktop_file_to_binary "$2"`" | |
[ "$binary" ] || exit_failure_file_missing | |
gconftool-2 --type string --set /desktop/gnome/url-handlers/$1/command "$binary %s" | |
gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/needs_terminal false | |
gconftool-2 --type bool --set /desktop/gnome/url-handlers/$1/enabled true | |
} | |
# }}} GNOME | |
# {{{ GNOME 3.x | |
get_url_scheme_handler_gnome3() | |
{ | |
get_browser_mime "x-scheme-handler/$1" | |
} | |
check_url_scheme_handler_gnome3() | |
{ | |
desktop="$2" | |
check="`desktop_file_to_binary "$2"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
browser="`get_browser_mime "x-scheme-handler/$1"`" | |
if [ x"$browser" != x"$desktop" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
exit_success | |
} | |
set_url_scheme_handler_gnome3() | |
{ | |
binary="`desktop_file_to_binary "$2"`" | |
[ "$binary" ] || exit_failure_file_missing | |
set_browser_mime "$2" || return | |
# Set the default browser. | |
set_browser_mime "$2" "x-scheme-handler/$1" || return | |
} | |
# }}} GNOME 3.x | |
# {{{ xfce | |
get_url_scheme_handler_xfce() | |
{ | |
exit_unimplemented_default_handler "$1" | |
} | |
check_url_scheme_handler_xfce() | |
{ | |
exit_unimplemented_default_handler "$1" | |
} | |
set_url_scheme_handler_xfce() | |
{ | |
exit_unimplemented_default_handler "$1" | |
} | |
# }}} xfce | |
# }}} default protocol handler | |
dispatch_specific() | |
{ | |
# The PROP comments in this function are used to generate the output of | |
# the --list option. The formatting is important. Make sure to line up the | |
# property descriptions with spaces so that it will look nice. | |
if [ x"$op" = x"get" ]; then | |
case "$parm" in | |
default-web-browser) # PROP: Default web browser | |
get_browser_$DE | |
;; | |
default-url-scheme-handler) # PROP: Default handler for URL scheme | |
get_url_scheme_handler_$DE "$1" | |
;; | |
*) | |
exit_failure_syntax | |
;; | |
esac | |
elif [ x"$op" = x"check" ]; then | |
case "$parm" in | |
default-web-browser) | |
check_desktop_filename "$1" | |
check_browser_$DE "$1" | |
;; | |
default-url-scheme-handler) | |
check_desktop_filename "$2" | |
check_url_scheme_handler_$DE "$1" "$2" | |
;; | |
*) | |
exit_failure_syntax | |
;; | |
esac | |
else # set | |
case "$parm" in | |
default-web-browser) | |
[ $# -eq 1 ] || exit_failure_syntax "unexpected/missing argument" | |
check_desktop_filename "$1" | |
set_browser_$DE "$1" | |
;; | |
default-url-scheme-handler) | |
[ $# -eq 2 ] || exit_failure_syntax "unexpected/missing argument" | |
check_desktop_filename "$2" | |
set_url_scheme_handler_$DE "$1" "$2" | |
;; | |
*) | |
exit_failure_syntax | |
;; | |
esac | |
fi | |
if [ $? -eq 0 ]; then | |
exit_success | |
else | |
exit_failure_operation_failed | |
fi | |
} | |
dispatch_generic() | |
{ | |
# We only know how to get or check the default web browser. | |
[ x"$op" != x"get" -a x"$op" != x"check" ] && exit_failure_operation_impossible | |
[ x"$parm" != x"default-web-browser" ] && exit_failure_operation_impossible | |
# First look in $BROWSER | |
if [ x"$BROWSER" != x ]; then | |
binary="`which "${BROWSER%%:*}"`" | |
else | |
# Debian and Ubuntu (and others?) have x-www-browser. | |
binary="`which x-www-browser`" | |
fi | |
[ "$binary" ] || exit_failure_operation_failed | |
binary="`readlink -f "$binary"`" | |
[ "$binary" ] || exit_failure_operation_failed | |
if [ x"$op" = x"get" ]; then | |
desktop="`binary_to_desktop_file "$binary"`" | |
basename "$desktop" | |
else | |
# $op = "check" | |
check="`desktop_file_to_binary "$1"`" | |
if [ -z "$check" ]; then | |
echo no | |
exit_success | |
fi | |
if [ x"$binary" != x"$check" ]; then | |
echo no | |
exit_success | |
fi | |
echo yes | |
fi | |
exit_success | |
} | |
if [ x"$1" = x"--list" ]; then | |
echo "Known properties:" | |
# Extract the property names from dispatch_specific() above. | |
grep "^[ ]*[^)]*) # PROP:" "$0" | sed -e 's/^[ ]*\([^)]*\)) # PROP: \(.*\)$/ \1 \2/' | sort | |
exit_success | |
fi | |
[ x"$1" != x ] || exit_failure_syntax "no operation given" | |
[ x"$2" != x ] || exit_failure_syntax "no parameter name given" | |
[ x"$1" = x"get" -o x"$3" != x ] || exit_failure_syntax "no parameter value given" | |
op="$1" | |
parm="$2" | |
shift 2 | |
if [ x"$op" != x"get" -a x"$op" != x"check" -a x"$op" != x"set" ]; then | |
exit_failure_syntax "invalid operation" | |
fi | |
detectDE | |
case "$DE" in | |
kde|gnome*|xfce) | |
dispatch_specific "$@" | |
;; | |
generic) | |
dispatch_generic "$@" | |
;; | |
*) | |
exit_failure_operation_impossible "unknown desktop environment" | |
;; | |
esac | |