#!/bin/sh # Copyright (C) 2014-2018, 2021-2022, 2024-2025 D. R. Commander. # All Rights Reserved. # Copyright (C) 2005-2008 Sun Microsystems, Inc. All Rights Reserved. # Copyright (C) 2002 Constantin Kaplinsky. All Rights Reserved. # # This is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. # If a TurboVNC session running GNOME or MATE is started from a local GNOME or # MATE session on the TurboVNC host, then the SESSION_MANAGER environment # variable will be set. We must unset that environment variable in order to # prevent interference between the host's window manager instance and the # TurboVNC session's window manager instance. unset SESSION_MANAGER # Similarly, if a TurboVNC session is started from a local Wayland session on # the TurboVNC host, then the WAYLAND_DISPLAY environment variable will be set. # We must unset that environment variable in order to prevent applications in # the TurboVNC session from using Wayland instead of X11. unset WAYLAND_DISPLAY # By default, GTK applications (including the GNOME window manager) will # attempt to display to a local Wayland session if one is active. This forces # those applications to display to the TurboVNC session. GDK_BACKEND=x11; export GDK_BACKEND # If a TurboVNC session will run a (reasonably modern) window manager, then the # session must have a D-Bus session bus instance. On Red Hat/Fedora (and # derivatives), SuSE/openSUSE, and FreeBSD, xinitrc and Xsession automatically # create a new session bus instance if the DBUS_SESSION_BUS_ADDRESS environment # variable is empty, so we used to unset that variable at this point in the # script. However, on other operating systems (particularly Debian 10+ and # Ubuntu 18.04+), it is necessary to explicitly create a new session bus # instance by invoking dbus-launch. # # If TVNC_USERDBUS is set to 1 in the environment (which will be the case if # $userDBus = 1 in turbovncserver.conf or -userdbus is passed to vncserver), # then we forego creating a unique D-Bus session bus instance for the TurboVNC # session and use the per-user D-Bus session bus instance provided by systemd # instead. That improves cgroup v2 compatibility at the expense of # multi-session capability. case "$DBUS_SESSION_BUS_ADDRESS" in unix:path=/run/user/*) ;; *) unset TVNC_USERDBUS ;; esac if [ "$TVNC_USERDBUS" != "1" ]; then DBUS_LAUNCH= if [ -x /usr/bin/dbus-launch ]; then DBUS_LAUNCH=/usr/bin/dbus-launch elif [ -x /usr/local/bin/dbus-launch ]; then DBUS_LAUNCH=/usr/local/bin/dbus-launch fi if [ "$DBUS_LAUNCH" != "" ]; then eval `$DBUS_LAUNCH --sh-syntax --exit-with-session` export DBUS_SESSION_BUS_ADDRESS echo "xstartup.turbovnc: Creating new session bus instance:" echo "xstartup.turbovnc: $DBUS_SESSION_BUS_ADDRESS" else # If we get here, then dbus-launch was not found, DBUS_SESSION_BUS_ADDRESS # is unlikely to be set, and Xsession would subsequently fail on the # aforementioned operating systems. Thus, unsetting # DBUS_SESSION_BUS_ADDRESS here is just a belt-and-suspenders measure to # help ensure that any window manager that requires D-Bus will fail sooner # rather than later. unset DBUS_SESSION_BUS_ADDRESS fi unset DBUS_LAUNCH fi # Specify that the window manager should use X11 rather than Wayland. XDG_SESSION_TYPE=x11; export XDG_SESSION_TYPE OS=`uname -s` # Emulate GDM find_session() { for SESSION in $SESSIONS; do if [ "$XSESSIONSDIR" != "" -a -f $XSESSIONSDIR/$SESSION.desktop ]; then DESKTOP_SESSION=$SESSION; export DESKTOP_SESSION break fi done # On Fedora 40 and later, gnome-classic.desktop lives in # /usr/share/wayland-sessions. More generally, there is nothing # Wayland-specific about the session desktop files in # /usr/share/wayland-sessions, so we can safely use them as well. if [ "$DESKTOP_SESSION" = "" -a \ "$XSESSIONSDIR" = "/usr/share/xsessions" ]; then for SESSION in $SESSIONS; do if [ -f /usr/share/wayland-sessions/$SESSION.desktop ]; then DESKTOP_SESSION=$SESSION; export DESKTOP_SESSION XSESSIONSDIR=/usr/share/wayland-sessions break fi done fi if [ "$DESKTOP_SESSION" = "" ]; then if [ "$TVNC_WM" = "" ]; then echo "xstartup.turbovnc: The session desktop file for the default window manager was" echo "xstartup.turbovnc: not found at:" else echo "xstartup.turbovnc: The session desktop file for the '$TVNC_WM'" echo "xstartup.turbovnc: window manager was not found at:" fi for SESSION in $SESSIONS; do echo "xstartup.turbovnc: $XSESSIONSDIR/$SESSION.desktop" done exit 1 fi unset SESSIONS } XSESSIONSDIR= if [ -d /usr/share/xsessions ]; then XSESSIONSDIR=/usr/share/xsessions elif [ -d /usr/local/share/xsessions ]; then XSESSIONSDIR=/usr/local/share/xsessions fi GREP=grep if [ -x /usr/bin/ggrep ]; then GREP=ggrep fi SED=sed if [ -x /usr/bin/gsed ]; then SED=gsed fi NOXSESSION=0 case "$TVNC_WM" in # Appending :noxsession to the window manager name causes the window manager # to be launched directly rather than through the Xsession script. No window # managers are known to require this, but the feature is retained for # testing/debugging purposes. 2d | 2d:noxsession) if [ "$TVNC_WM" = "2d:noxsession" ]; then NOXSESSION=1 TVNC_WM=`echo $TVNC_WM | $SED -r 's/:noxsession$//g'` fi # RHEL 7+, Fedora: gnome-classic # Ubuntu 12: ubuntu-2d # Ubuntu 14: gnome-fallback # Ubuntu 16+: gnome-flashback-metacity SESSIONS="gnome-classic gnome-fallback ubuntu-2d 2d-gnome gnome-flashback-metacity" find_session unset TVNC_WM ;; *) case "$TVNC_WM" in *:noxsession) NOXSESSION=1 TVNC_WM=`echo $TVNC_WM | $SED -r 's/:noxsession$//g'` ;; *) ;; esac if [ "$TVNC_WM" = "" ]; then # No window manager was specified. Use GNOME, Unity, MATE, or Xfce (in # that order) if a corresponding session desktop file exists. SESSIONS="gnome ubuntu mate xfce" find_session else # For backward compatibility with TurboVNC 2.2.x, we allow a window # manager's startup script (e.g. mate-session, gnome-session) to be # specified using -wm / $wm, but if there is a matching session desktop # file for it, we use that instead. SESSIONS="`echo $TVNC_WM | $SED -r 's/^.*\/|-session$//g'`" find_session unset TVNC_WM fi ;; esac XSESSION= if [ "$DESKTOP_SESSION" != "" ]; then # A window manager was specified, or the default window manager will be used, # and the corresponding session desktop file exists. Set the appropriate # environment variables. GDMSESSION=$DESKTOP_SESSION; export GDMSESSION XDG_SESSION_DESKTOP=$DESKTOP_SESSION; export XDG_SESSION_DESKTOP echo "xstartup.turbovnc: Using '$DESKTOP_SESSION' window manager in" echo "xstartup.turbovnc: $XSESSIONSDIR/$DESKTOP_SESSION.desktop" # Parse the session desktop file to determine the window manager's startup # command, and set the TVNC_WM environment variable accordingly. if $GREP -qE "^Exec\s*=" $XSESSIONSDIR/$DESKTOP_SESSION.desktop; then TVNC_WM=`$GREP -E "^Exec\s*=" $XSESSIONSDIR/$DESKTOP_SESSION.desktop | $SED -r 's/^[^=]+=[[:space:]]*//g'` if [ "$NOXSESSION" != "1" ]; then if [ -x /etc/X11/xinit/Xsession ]; then XSESSION=/etc/X11/xinit/Xsession elif [ -x /etc/X11/Xsession ]; then XSESSION=/etc/X11/Xsession fi fi fi # Parse the session desktop file to determine the window manager's desktop # name. for KEY in DesktopNames X-LightDM-DesktopName; do if $GREP -qE "^$KEY\s*=" $XSESSIONSDIR/$DESKTOP_SESSION.desktop; then XDG_CURRENT_DESKTOP=`$GREP -E "^$KEY\s*=" $XSESSIONSDIR/$DESKTOP_SESSION.desktop | $SED -r 's/(^[^=]+=[[:space:]]*|;$)//g' | $SED -r 's/;/:/g'` export XDG_CURRENT_DESKTOP fi done fi if [ "$TVNC_VGL" = "1" ]; then # If launching the window manager using VirtualGL, invoke vglrun through # ssh-agent. On some operating systems, Xsession launches the window manager # using ssh-agent if there is no active ssh-agent session, and ssh-agent # clobbers LD_PRELOAD. Thus, we explicitly create an ssh-agent session for # VirtualGL. if [ -z "$SSH_AGENT_PID" -a -x /usr/bin/ssh-agent ]; then TVNC_SSHAGENT=/usr/bin/ssh-agent fi if [ -z "$TVNC_VGLRUN" ]; then TVNC_VGLRUN="vglrun +wm" fi fi if [ "$TVNC_WM" = "" ]; then echo "xstartup.turbovnc: No window manager was specified, and the default window" echo "xstartup.turbovnc: manager is unavailable." exit 1 fi # Start the window manager. if [ "$XSESSION" != "" ]; then echo xstartup.turbovnc: Executing $TVNC_SSHAGENT $TVNC_VGLRUN $XSESSION \"$TVNC_WM\" exec $TVNC_SSHAGENT $TVNC_VGLRUN $XSESSION "$TVNC_WM" else echo xstartup.turbovnc: Executing $TVNC_SSHAGENT $TVNC_VGLRUN $TVNC_WM exec $TVNC_SSHAGENT $TVNC_VGLRUN $TVNC_WM fi