wineshelllink: Use FreeDesktop standard to create Wine
menu structure.
Jeremy White
jwhite at winehq.org
Fri Nov 24 15:32:59 CST 2006
I would strongly recommend that this be done instead with
xdg-utils:
http://portland.freedesktop.org/wiki/XdgUtils
That will allow us to avoid the pain of maintaining our own
implementation, and allow distro vendors to make their distro
work with Wine just by supplying a working version of xdg-utils.
The trick is whether or not we can persuade Alexandre and/or all
of the Wine packagers to include xdg-utils by default in distributions.
Cheers,
Jeremy
Vitaliy Margolen wrote:
> Change Log:
> wineshelllink: Use FreeDesktop standard to create Wine menu structure.
>
> The major changes include:
> - Use WM independent paths for all generated files.
> - Dynamically build .menu and .directory files to create menu structure.
> - Store icons in local icon store using their "cryptic" names to avoid conflicts.
> - Number of other changes required for compatibility.
> Note: .desktop links are still stored in a directory structure representing
> Start Menu. This is done for possible future expansion.
>
> This new approach should work with KDE, Gnome and other XDG compliant managers.
> I have verified this with recent versions of KDE and Gnome on several distros.
>
> However there are might be some problems with some custom changes some distros
> might have. As an example SuSE has special feature that doesn't work right:
> https://bugzilla.novell.com/show_bug.cgi?id=188110
>
> The question of removing these links after programs have been uninstalled still open.
> There are number of possible ways to solve it. The simplest would be symlinking
> directories containing .desktop files. However that might brake whole menu structure.
> ---
> tools/wineshelllink | 258 ++++++++++++++++++++++----------------------------
> 1 files changed, 114 insertions(+), 144 deletions(-)
>
>
> ------------------------------------------------------------------------
>
> diff --git a/tools/wineshelllink b/tools/wineshelllink
> index db65efa..5d91afc 100755
> --- a/tools/wineshelllink
> +++ b/tools/wineshelllink
> @@ -4,6 +4,7 @@
> # This is used by the IShellLink interface
> #
> # Copyright 2000 Alexandre Julliard
> +# Copyright 2006 Vitaliy Margolen
> #
> # This library is free software; you can redistribute it and/or
> # modify it under the terms of the GNU Lesser General Public
> @@ -22,8 +23,7 @@
>
> # Note that the link is a relative unix-style path name. Since the / character
> # is not valid in Windows filenames it is an adequate separator to show the
> -# menu structure. (This program may need to split the menu structure out for
> -# implementing xdg-style menus)
> +# menu structure.
>
> mode=""
> args=""
> @@ -82,176 +82,146 @@ if [ -z "$link" ] ; then
> usage
> fi
>
> -kde_entry()
> +desktop_entry()
> {
> - xname=`basename "$link"`
> - cat <<EOF
> -# KDE Config File
> -[KDE Desktop Entry]
> -Name=$xname
> -Exec=wine '$path' $args
> -Type=Application
> -Comment=$descr
> -EOF
> - [ -z "$workdir" ] || echo "Path=\"$workdir\""
> - [ -z "$xpmicon" ] || echo "Icon=$xpmicon"
> -}
> -
> -gnome_entry()
> -{
> - xname=`basename "$link"`
> cat <<EOF
> [Desktop Entry]
> -Name=$xname
> +Name=$linkname
> Exec=wine "$path" $args
> Type=Application
> -Comment=$descr
> EOF
> + [ -z "$descr" ] || echo "Comment=$descr"
> [ -z "$workdir" ] || echo "Path=$workdir"
> [ -z "$xpmicon" ] || echo "Icon=$xpmicon"
> }
>
> -mdk_entry()
> +directory_entry()
> {
> - base=`basename "$link"`
> - section=`dirname "$link"`
> - [ -z "$icon" ] || xicon="icon=\"$xpmicon\""
> - pathmenu=`echo "$path" | sed 's+\\\\+\\\\\\\\+g'`
> - echo "?package(local.Wine):needs=x11 section=\"/Wine/$section\" title=\"$base\" longtitle=\"$descr\" command=\"wine '$pathmenu' $args\" $xicon"
> + cat <<EOF
> +[Desktop Entry]
> +Type=Directory
> +EOF
> + if [ "$1" == "wine" ] ; then
> + echo "Name=Wine"
> + echo "Icon=wine"
> + else
> + echo "Name=$1"
> + echo "Icon=folder"
> + fi
> }
>
> # copy the icon file to a specified dir and set xpmicon to the resulting path
> copy_icon()
> {
> - dir="$1"
> - mkdir -p "$dir"
> - mkdir -p "$dir/""`dirname "$link"`" || true
> - if [ -f "$icon" ]
> - then
> - cp "$icon" "$dir/$link.xpm"
> - xpmicon="$dir/$link.xpm"
> - else
> - xpmicon=""
> - fi
> + if [ -f "$icon" ]
> + then
> + xpmicon=`basename "$icon" .xpm`
> +
> + mkdir -p "$1"
> + cp "$icon" "$1/$xpmicon.xpm"
> + else
> + xpmicon=""
> + fi
> }
>
> -# Debian/Mandrake
> -
> -type update-menus > /dev/null 2>&1
> -if [ $? = 0 -a $mode = "menu" ]
> -then
> - iconname="`basename "$link"`.xpm"
> - dir="$HOME/.menu/icons"
> - if [ -f "$icon" ]
> - then
> - mkdir -p "$dir"
> - cp "$icon" "$dir/$iconname"
> - xpmicon="$dir/$iconname"
> - else
> - xpmicon=""
> - fi
> - mdk_entry >> "$HOME/.menu/wine"
> - if [ -d "/usr/lib/menu" ] && [ -w "/usr/lib/menu" ]
> - then
> - mdk_entry >> "/usr/lib/menu/wine"
> - fi
> - update-menus > /dev/null 2>&1
> -fi
> +# XDG
>
> -# KDE
> +xdg_config_dir="$XDG_CONFIG_HOME"
> +[ -n "$xdg_user_dir" ] || xdg_config_dir="$HOME/.config"
> +xdg_config_dir="$xdg_config_dir/menus/applications-merged"
>
> -if [ -d "$HOME/.kde" ]
> -then
> - kdeversion=0
> - if type kde-config >/dev/null 2>&1
> - then
> - kdeversion=`kde-config -v | grep KDE: | sed -n "s/^KDE: \([^.]*\)\..*$/\1/p"`
> - fi
> +xdg_data_dir="$XDG_DATA_HOME"
> +[ -n "$xdg_data_dir" ] || xdg_data_dir="$HOME/.local/share"
>
> - if [ $kdeversion -ge 2 ]
> - then
> - copy_icon "$HOME/.kde/share/applnk/Wine"
> - if [ $mode = "menu" ]
> - then
> - gnome_entry > "$HOME/.kde/share/applnk/Wine/$link.desktop"
> - elif [ -d "$HOME/Desktop" ]
> - then
> - gnome_entry > "$HOME/Desktop/$link.desktop"
> +# Create common directories
> +mkdir -p "$xdg_config_dir"
> +mkdir -p "$xdg_data_dir/desktop-directories"
> +
> +get_menu_entries()
> +{
> + tmp="$xdg_config_dir/$1.menu"
> +
> + if [ -r "$tmp" ] ; then
> + awk '
> +BEGIN { RS="<" }
> +/^Filename/ {
> + if (match($0,/>/)) {
> + print substr($0,RSTART+1)
> + }
> +}' $tmp
> fi
> - else
> - copy_icon "$HOME/.kde/share/applnk/Wine"
> - if [ $mode = "menu" ]
> - then
> - kde_entry > "$HOME/.kde/share/applnk/Wine/$link.kdelnk"
> +}
>
> - # KDE 1.x kludge. Wake up KDE, if we can find kpanel running
> - type kwmcom >/dev/null 2>/dev/null && \
> - ps u -C kpanel >/dev/null 2>/dev/null && \
> - kwmcom kpanel:restart
> +# Input
> +# menu file name
> +# new item
> +write_menu_file()
> +{
> + tmpfile=`mktemp`
> + (
> + echo '<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"'
> + echo '"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">'
> + echo '<Menu>'
> + echo ' <Name>Applications</Name>'
> +
> + IFS="-"
> +
> + fullname='wine'
> + for i in $1; do
> + echo " <Menu>"
> + echo " <Name>$fullname-$i</Name>"
> + echo " <Directory>$fullname-$i.directory</Directory>"
> +
> + dir_file_name="$xdg_data_dir/desktop-directories/$fullname-$i.directory"
> + if [ ! -f "$dir_file_name" ] ; then
> + directory_entry "$i" > "$dir_file_name"
> + fi
> + test "$i" = "wine" || fullname="$fullname-$i"
> + done
> +
> + echo " <Include>"
> +
> + IFS="
> +"
> + for i in $(get_menu_entries "$1"); do
> + test "$i" = "$2" && continue
> + echo " <Filename>$i</Filename>"
> + done
> +
> + # New record
> + echo " <Filename>$2</Filename>"
> + echo " </Include>"
> +
> + IFS='-'
> + for i in $1; do
> + echo " </Menu>"
> + done
> + echo '</Menu>'
> + ) > $tmpfile
> + chmod 0600 $tmpfile
> +
> + mv -f $tmpfile "$xdg_config_dir/$1.menu"
> +}
>
> - elif [ -d "$HOME/Desktop" ]
> - then
> - kde_entry > "$HOME/Desktop/$link.kdelnk"
> - # KDE 1.x kludge: wake up KDE, if we can find kfm running...
> - type kfmclient >/dev/null 2>/dev/null && \
> - ps u -C kfm >/dev/null 2>/dev/null && \
> - kfmclient refreshDesktop
> - fi
> - fi
> -fi
>
> -if [ -d "$HOME/.kde2" ]
> -then
> - copy_icon "$HOME/.kde2/share/applnk/Wine"
> - if [ $mode = "menu" ]
> - then
> - gnome_entry > "$HOME/.kde2/share/applnk/Wine/$link.desktop"
> - else
> - if [ -d "$HOME/Desktop2" ]
> - then
> - gnome_entry > "$HOME/Desktop2/$link.desktop"
> - fi
> - if [ -d "$HOME/Desktop" ]
> - then
> - gnome_entry > "$HOME/Desktop/$link.desktop"
> - fi
> - fi
> -fi
> +copy_icon "$xdg_data_dir/icons"
>
> -if [ -d "$HOME/.kde3/share/applnk" ]
> -then
> - copy_icon "$HOME/.kde3/share/applnk/Wine"
> - if [ $mode = "menu" ]
> - then
> - gnome_entry > "$HOME/.kde3/share/applnk/Wine/$link.desktop"
> - else
> - if [ -d "$HOME/Desktop3" ]
> - then
> - gnome_entry > "$HOME/Desktop3/$link.desktop"
> - fi
> - if [ -d "$HOME/Desktop2" ]
> - then
> - gnome_entry > "$HOME/Desktop2/$link.desktop"
> - fi
> - if [ -d "$HOME/Desktop" ]
> - then
> - gnome_entry > "$HOME/Desktop/$link.desktop"
> +linkname=`basename "$link"`
> +
> +if [ $mode = "menu" ] ; then
> + mkdir -p "$xdg_data_dir/applications/wine/`dirname "$link"`"
> +
> + linkpath=`dirname "$link" | sed 's!/!-!g'`
> + if [ "$linkpath" == "." ] ; then
> + linkpath=""
> + else
> + linkpath="-$linkpath"
> fi
> - fi
> -fi
>
> -# Gnome
> -
> -if [ -d "$HOME/.gnome" ]
> -then
> - copy_icon "$HOME/.gnome/apps/Wine"
> - if [ $mode = "menu" ]
> - then
> - gnome_entry > "$HOME/.gnome/apps/Wine/$link.desktop"
> - elif [ -d "$HOME/.gnome-desktop" ]
> - then
> - gnome_entry > "$HOME/.gnome-desktop/$link.desktop"
> - fi
> + desktop_entry > "$xdg_data_dir/applications/wine/$link.desktop"
> + write_menu_file "wine$linkpath" "wine$linkpath-$linkname.desktop"
> +else
> + desktop_entry > "$HOME/Desktop/$linkname.desktop"
> fi
>
> exit 0
>
>
>
> ------------------------------------------------------------------------
>
>
More information about the wine-devel
mailing list