blob: e101297aa617a28c168a7efc84bbf817dbcd0b98 [file] [log] [blame]
#!/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