diff --git a/indra/newview/linux_tools/com.secondlife.indra.viewer.desktop b/indra/newview/linux_tools/com.secondlife.indra.viewer.desktop new file mode 100644 index 00000000000..4ce2765714a --- /dev/null +++ b/indra/newview/linux_tools/com.secondlife.indra.viewer.desktop @@ -0,0 +1,24 @@ +[Desktop Entry] +Version=1.5 +Name=Second Life +GenericName=Second Life Viewer +Comment=Client for the Online Virtual World, Second Life +Path=@INSTALLATION_PREFIX@ +Exec=@INSTALLATION_PREFIX@/secondlife %u +Icon=com.secondlife.indra.viewer +Terminal=false +Type=Application +Categories=Game;Simulation; +StartupNotify=true +StartupWMClass="com.secondlife.indra.viewer" +MimeType=x-scheme-handler/secondlife; +PrefersNonDefaultGPU=true +Actions=DefaultGPU;AssociateMIME; + +[Desktop Action DefaultGPU] +Exec=env __GLX_VENDOR_LIBRARY_NAME=\"\" @INSTALLATION_PREFIX@/secondlife +Name=Launch on default GPU + +[Desktop Action AssociateMIME] +Exec=@INSTALLATION_PREFIX@/etc/register_secondlifeprotocol.sh +Name=Associate SLURLs diff --git a/indra/newview/linux_tools/handle_secondlifeprotocol.sh b/indra/newview/linux_tools/handle_secondlifeprotocol.sh old mode 100755 new mode 100644 index 203012132e7..3fdabc7f842 --- a/indra/newview/linux_tools/handle_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/handle_secondlifeprotocol.sh @@ -1,17 +1,29 @@ #!/bin/bash -# Send a URL of the form secondlife://... to Second Life. +# Note: This script is no longer used, as the main wrapper script is now handling SLURLs directly. + +# Send a URL of the form secondlife://... to any running viewer, if not, launch the default viewer. # -URL="$1" +sl_url="$1" -if [ -z "$URL" ]; then - echo Usage: $0 secondlife://... - exit +echo "Got SLURL: ${sl_url}" +if [ -z "${sl_url}" ]; then + echo "Usage: $0 secondlife:// ..." + exit fi -RUN_PATH=`dirname "$0" || echo .` -cd "${RUN_PATH}/.." +run_path=$(dirname "$0" || echo .) -exec ./secondlife -url \'"${URL}"\' +#Poll DBus to get a list of registered services, then look through the list for the Second Life API Service - if present, this means a viewer is running, if not, then no viewer is running and a new instance should be launched +service_name="com.secondlife.ViewerAppAPIService" #Name of Second Life DBus service. This should be the same across all viewers. +if dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep -q "${service_name}"; then + echo "Second Life running, sending to DBus..."; + exec dbus-send --type=method_call --dest="${service_name}" /com/secondlife/ViewerAppAPI com.secondlife.ViewerAppAPI.GoSLURL string:"${sl_url}" +else + echo "Second Life not running, launching new instance..."; + cd "${run_path}"/.. || exit + #Go to .sh location (/etc), then up a directory to the viewer location + exec ./secondlife -url "${sl_url}" +fi diff --git a/indra/newview/linux_tools/install.sh b/indra/newview/linux_tools/install.sh old mode 100755 new mode 100644 index c94510267ad..ee9b43161ee --- a/indra/newview/linux_tools/install.sh +++ b/indra/newview/linux_tools/install.sh @@ -10,6 +10,18 @@ SCRIPTSRC=`readlink -f "$0" || echo "$0"` RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` tarball_path=${RUN_PATH} +build_data_file="${RUN_PATH}/build_data.json" +if [ -f "${build_data_file}" ]; then + version=$(sed -n 's/.*"Version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + channel=$(sed -n 's/.*"Channel"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "${build_data_file}") + installdir_name=$(echo "$channel" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' )-install +else + echo "Error: File ${build_data_file} not found." >&2 + exit 1 +fi + +echo "Installing ${channel} version ${version}" + function prompt() { local prompt=$1 @@ -58,13 +70,18 @@ function homedir_install() exit 0 fi - install_to_prefix "$HOME/.secondlife-install" - $HOME/.secondlife-install/etc/refresh_desktop_app_entry.sh + if [ -n "$XDG_DATA_HOME" ] ; then + local install_prefix="$XDG_DATA_HOME/$installdir_name" #$XDG_DATA_HOME is a synonym for $HOME/.local/share/ unless the user has specified otherwise (unlikely). + else + local install_prefix="$HOME/.local/share/$installdir_name" + fi + install_to_prefix "$install_prefix" + update_desktop_entry "$install_prefix" } function root_install() { - local default_prefix="/opt/secondlife-install" + local default_prefix="/opt/$installdir_name" echo -n "Enter the desired installation directory [${default_prefix}]: "; read @@ -77,7 +94,7 @@ function root_install() install_to_prefix "$install_prefix" mkdir -p /usr/local/share/applications - ${install_prefix}/etc/refresh_desktop_app_entry.sh + update_desktop_entry "$install_prefix" } function install_to_prefix() @@ -98,6 +115,24 @@ function backup_previous_installation() mv "$1" "$backup_dir" || die "Failed to create backup of existing installation!" } +#Below function is not currently used as the desktop environment should prompt the user to associate SLURLs upon first use following installation, however is included here if it's determined in future to be needed. +function set_slurl_handler() +{ + local install_prefix=$1 + echo + prompt "Would you like to set Second Life as your default SLURL handler? [Y/N]: " + if [ $? -eq 0 ]; then + return 0 + fi + "${install_prefix}"/etc/register_secondlifeprotocol.sh #Should prompt the desktop environment to set association. Normally not needed as it will prompt upon the first use of a SLURL after installation. +} + +function update_desktop_entry() +{ + local install_prefix=$1 + sed -i "s|@INSTALLATION_PREFIX@|$install_prefix|g" "$install_prefix/etc/com.secondlife.SecondLifeViewer.desktop" + "${install_prefix}"/etc/refresh_desktop_app_entry.sh +} if [ "$UID" == "0" ]; then root_install diff --git a/indra/newview/linux_tools/refresh_desktop_app_entry.sh b/indra/newview/linux_tools/refresh_desktop_app_entry.sh old mode 100755 new mode 100644 index 84af7505eab..7bfaa906d25 --- a/indra/newview/linux_tools/refresh_desktop_app_entry.sh +++ b/indra/newview/linux_tools/refresh_desktop_app_entry.sh @@ -10,28 +10,12 @@ function install_desktop_entry() local installation_prefix="$1" local desktop_entries_dir="$2" - local desktop_entry="\ -[Desktop Entry]\n\ -Name=Second Life\n\ -GenericName=Second Life Viewer\n\ -Comment=Client for the On-line Virtual World, Second Life\n\ -Path=${installation_prefix}\n\ -Exec=${installation_prefix}/secondlife\n\ -Icon=${installation_prefix}/secondlife_icon.png\n\ -Terminal=false\n\ -Type=Application\n\ -Categories=Game;Simulation;\n\ -StartupNotify=true\n\ -StartupWMClass="com.secondlife.indra.viewer"\n\ -X-Desktop-File-Install-Version=3.0" + printf "Installing menu entries via XDG..." + xdg-icon-resource install --novendor --size 256 "${installation_prefix}/secondlife_icon.png" "com.secondlife.indra.viewer" + #NOTE: Above command takes the path to the icon to install && The name of the icon to be used by XDG. This should always be in the format of "xViewer" to avoid potential naming conflicts, as per XDG spec. + xdg-desktop-menu install --novendor "${installation_prefix}"/etc/com.secondlife.indra.viewer.desktop - echo " - Installing menu entries in ${desktop_entries_dir}" - WORK_DIR=`mktemp -d` - echo -e $desktop_entry > "${WORK_DIR}/secondlife-viewer.desktop" || "Failed to install application menu!" - desktop-file-install --dir="${desktop_entries_dir}" ${WORK_DIR}/secondlife-viewer.desktop - rm -r $WORK_DIR - - update-desktop-database "${desktop_entries_dir}" + xdg-desktop-menu forceupdate #Above command should update the menu system, but do it a second time just in case. } if [ "$UID" == "0" ]; then diff --git a/indra/newview/linux_tools/register_secondlifeprotocol.sh b/indra/newview/linux_tools/register_secondlifeprotocol.sh old mode 100755 new mode 100644 index d41e6dd6cbb..69527d3c915 --- a/indra/newview/linux_tools/register_secondlifeprotocol.sh +++ b/indra/newview/linux_tools/register_secondlifeprotocol.sh @@ -3,55 +3,5 @@ # Register a protocol handler (default: handle_secondlifeprotocol.sh) for # URLs of the form secondlife://... # - -HANDLER="$1" - -SCRIPTSRC=`readlink -f "$0" || echo "$0"` -RUN_PATH=`dirname "${SCRIPTSRC}" || echo .` - -install_prefix="$(realpath -- "${RUN_PATH}/..")" - -cd "${RUN_PATH}/.." - -if [ -z "$HANDLER" ]; then - HANDLER=$install_prefix/etc/handle_secondlifeprotocol.sh -fi - -function install_desktop_entry() -{ - local installation_prefix="$1" - local desktop_entries_dir="$2" - - local desktop_entry="\ -[Desktop Entry]\n\ -Name=Second Life SLURL handler\n\ -Path=${installation_prefix}\n\ -Exec=${HANDLER} %u\n\ -Icon=${installation_prefix}/secondlife_icon.png\n\ -Terminal=false\n\ -Type=Application\n\ -StartupNotify=true\n\ -StartupWMClass="com.secondlife.indra.viewer"\n\ -NoDisplay=true\n\ -MimeType=x-scheme-handler/secondlife\n\ -X-Desktop-File-Install-Version=3.0" - - echo " - Installing protocol entries in ${desktop_entries_dir}" - WORK_DIR=`mktemp -d` - PROTOCOL_HANDLER="secondlife-protocol.desktop" - echo -e $desktop_entry > "${WORK_DIR}/${PROTOCOL_HANDLER}" || "Failed to create desktop file!" - desktop-file-install --dir="${desktop_entries_dir}" "${WORK_DIR}/${PROTOCOL_HANDLER}" || "Failed to install desktop file!" - rm -r $WORK_DIR - - xdg-mime default "${desktop_entries_dir}/${PROTOCOL_HANDLER}" x-scheme-handler/secondlife - - update-desktop-database "${desktop_entries_dir}" -} - -if [ "$UID" == "0" ]; then - # system-wide - install_desktop_entry "$install_prefix" /usr/local/share/applications -else - # user-specific - install_desktop_entry "$install_prefix" "$HOME/.local/share/applications" -fi +# Ask the Desktop Environment to change it's SLURL handler to this viewer. May prompt the user to select their preferred handler or do so silently depending on Desktop Environment. +xdg-settings set default-url-scheme-handler secondlife com.secondlife.indra.viewer.desktop diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh old mode 100755 new mode 100644 index 7e7a9a5e49c..cb3924b833c --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -30,10 +30,27 @@ echo "Running from ${RUN_PATH}" cd "${RUN_PATH}" # Re-register the secondlife:// protocol handler every launch, for now. -./etc/register_secondlifeprotocol.sh +#./etc/register_secondlifeprotocol.sh # Re-register the application with the desktop system every launch, for now. -./etc/refresh_desktop_app_entry.sh +#./etc/refresh_desktop_app_entry.sh + +# Above re-registering no longer used as viewer now registers itself via XDG and the Desktop Environment. + +#Below is a function to check if any additional parameters passed are a valid SLURL. +function is_valid_secondlife_uri() { + local uri="$1" + # Check if it starts with secondlife:// + if [[ ! "$uri" =~ ^secondlife:// ]]; then + return 1 + fi + # Pattern: secondlife:///// with optional additional parameters + if [[ "$uri" =~ ^secondlife://[^/]+/[0-9]+/[0-9]+/[0-9]+(/.*)?$ ]]; then + return 0 + else + return 1 + fi +} ## Before we mess with LD_LIBRARY_PATH, save the old one to restore for ## subprocesses that care. @@ -52,12 +69,22 @@ for ARG in "$@"; do fi done -# Run the program. -# Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the -# command line. But DO quote "${ARGS[@]}": preserve separate args as -# individually quoted. -$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}" -LL_RUN_ERR=$? +#Check if any additional arguments are valid SLURLs, and if so, check if a viewer instance is already running. If so, send the SLURL to be handled by the running viewer, instead of starting a new instance. +#Poll DBus to get a list of registered services, then look through the list for the Second Life API Service - if present, this means a viewer is running, if not, then no viewer is running and a new instance should be launched. +service_name="com.secondlife.ViewerAppAPIService" #Name of Second Life DBus service. This should be the same across all viewers. +if is_valid_secondlife_uri "${ARGS[@]}" && \ + dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep -q "${service_name}"; then + echo "Found a Second Life compatible Viewer running, sending SLURL to DBus..."; + exec dbus-send --type=method_call --dest="${service_name}" /com/secondlife/ViewerAppAPI com.secondlife.ViewerAppAPI.GoSLURL string:"${ARGS[@]}" +else + # Run the program. + # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the + # command line. But DO quote "${ARGS[@]}": preserve separate args as + # individually quoted. + echo "No running Second Life Viewer found, launching new instance..."; + $LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}" + LL_RUN_ERR=$? +fi # Handle any resulting errors if [ $LL_RUN_ERR -ne 0 ]; then diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 12705c4295e..13219a7a97b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1129,6 +1129,7 @@ def construct(self): self.path("handle_secondlifeprotocol.sh") self.path("register_secondlifeprotocol.sh") self.path("refresh_desktop_app_entry.sh") + self.path("com.secondlife.indra.viewer.desktop") self.path("install.sh") with self.prefix(dst="bin"):