]> source.dussan.org Git - tigervnc.git/commitdiff
Start sessions using session desktop file
authorPierre Ossman <ossman@cendio.se>
Fri, 27 Jul 2018 19:39:01 +0000 (21:39 +0200)
committerPierre Ossman <ossman@cendio.se>
Thu, 12 Mar 2020 10:26:04 +0000 (11:26 +0100)
This is how display managers (e.g. gdm or lightdm) start sessions
and is necessary to get the proper set of environment variables.

unix/vncserver/vncserver
unix/vncserver/vncserver.man

index ce45ebaf0949aa16f02284fef91ad63fa337c87c..71d4724065eddf1c18cf5deb2219a462787ecd16 100755 (executable)
@@ -48,34 +48,8 @@ $vncSystemConfigDir = "/etc/tigervnc";
 $vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
 $vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory";
 
-$skipxstartup = 0;
 $xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
 
-$xstartupFile = $vncUserDir . "/xstartup";
-$defaultXStartup
-    = ("#!/bin/sh\n\n".
-       "OS=`uname -s`\n".
-       "if [ \$OS = 'Linux' ]; then\n".
-       "  case \"\$WINDOWMANAGER\" in\n".
-       "    \*gnome\*)\n".
-       "      if [ -e /etc/SuSE-release ]; then\n".
-       "        PATH=\$PATH:/opt/gnome/bin\n".
-       "        export PATH\n".
-       "      fi\n".
-       "      ;;\n".
-       "  esac\n".
-       "fi\n".
-       "if [ -x /etc/X11/xinit/xinitrc ]; then\n".
-       "  exec /etc/X11/xinit/xinitrc\n".
-       "fi\n".
-       "if [ -f /etc/X11/xinit/xinitrc ]; then\n".
-       "  exec sh /etc/X11/xinit/xinitrc\n".
-       "fi\n".
-       "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n".
-       "xsetroot -solid grey\n".
-       "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
-       "twm\n");
-
 chop($host = `uname -n`);
 
 if (-d "/etc/X11/fontpath.d") {
@@ -117,7 +91,7 @@ if ($fontPath eq "") {
 # Check command line options
 
 &ParseOptions("-kill",1,"-help",0,"-h",0,"--help",0,"-list",0,
-             "-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1);
+             "-fg",0,"-autokill",0);
 
 &Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
 
@@ -125,13 +99,6 @@ if ($fontPath eq "") {
 
 &List() if ($opt{'-list'});
 
-if ($opt{'-noxstartup'}) {
-    $skipxstartup = 1;
-}
-if ($opt{'-xstartup'}) {
-    $xstartupFile = $opt{'-xstartup'};
-}
-
 # Create the user's vnc directory if necessary.
 if (!(-e $vncUserDir)) {
     if (!mkdir($vncUserDir,0755)) {
@@ -223,6 +190,52 @@ if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
 $desktopLog = "$vncUserDir/$host:$displayNumber.log";
 unlink($desktopLog);
 
+#
+# Find a desktop session to run
+#
+
+my $sessionname;
+my %session;
+
+$sessionname = delete $config{'session'};
+
+if ($sessionname) {
+  %session = LoadXSession($sessionname);
+  if (!%session) {
+    warn "Could not load configured desktop session $sessionname\n";
+    $sessionname = undef;
+  }
+}
+
+if (!$sessionname) {
+  foreach $file (glob("/usr/share/xsessions/*.desktop")) {
+    ($name) = $file =~ /^.*\/(.*)[.]desktop$/;
+    %session = LoadXSession($name);
+    if (%session) {
+      $sessionname = $name;
+      last;
+    }
+  }
+}
+
+if (!$sessionname) {
+  die "Could not find a desktop session to run\n";
+}
+
+warn "Using desktop session $sessionname\n";
+
+if (!$session{'Exec'}) {
+  die "No command specified for desktop session\n";
+}
+
+$ENV{GDMSESSION} = $sessionname;
+$ENV{DESKTOP_SESSION} = $sessionname;
+$ENV{XDG_SESSION_DESKTOP} = $sessionname;
+
+if ($session{'DesktopNames'}) {
+    $ENV{XDG_DESKTOP_NAMES} = $session{'DesktopNames'} =~ s/;/:/gr;
+}
+
 # Make an X server cookie and set up the Xauthority file
 # mcookie is a part of util-linux, usually only GNU/Linux systems have it.
 $cookie = `mcookie`;
@@ -298,21 +311,9 @@ unless (kill 0, `cat $pidFile`) {
 
 warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
 
-# Create the user's xstartup script if necessary.
-if (! $skipxstartup) {
-    if (!(-e "$xstartupFile")) {
-       warn "Creating default startup script $xstartupFile\n";
-       open(XSTARTUP, ">$xstartupFile");
-        print XSTARTUP $defaultXStartup;
-        close(XSTARTUP);
-        chmod 0755, "$xstartupFile";
-    }
-}
-
 # Run the X startup script.
-if (! $skipxstartup) {
-    warn "Starting applications specified in $xstartupFile\n";
-}
+warn "Starting desktop session $sessionname\n";
+
 warn "Log file is $desktopLog\n\n";
 
 # If the unix domain socket exists then use that (DISPLAY=:n) otherwise use
@@ -328,24 +329,16 @@ if (-e "/tmp/.X11-unix/X$displayNumber" ||
 $ENV{VNCDESKTOP}= $desktopName;
 
 if ($opt{'-fg'}) {
-    if (! $skipxstartup) {
-        system("$xstartupFile >> " . &quotedString($desktopLog) . " 2>&1");
-    }
+    system("$Xsession $session{'Exec'} >> " . &quotedString($desktopLog) . " 2>&1");
     if (kill 0, `cat $pidFile`) {
         $opt{'-kill'} = ':'.$displayNumber;
         &Kill();
     }
 } else {
     if ($opt{'-autokill'}) {
-       if (! $skipxstartup) {
-            system("($xstartupFile; $0 -kill :$displayNumber) >> "
-            . &quotedString($desktopLog) . " 2>&1 &");
-       }
+        system("$Xsession $session{'Exec'}; $0 -kill :$displayNumber) >> " . &quotedString($desktopLog) . " 2>&1 &");
     } else {
-       if (! $skipxstartup) {
-            system("$xstartupFile >> " . &quotedString($desktopLog)
-            . " 2>&1 &");
-       }
+        system("$Xsession $session{'Exec'} >> " . &quotedString($desktopLog) . " 2>&1 &");
     }
 }
 
@@ -410,6 +403,59 @@ sub GetDisplayNumber
 }
 
 
+#
+# Load a session desktop file
+#
+sub LoadXSession {
+  local ($name) = @_;
+  my $file, $found_group, %session;
+
+  $file = "/usr/share/xsessions/$name.desktop";
+
+  if (!stat($file)) {
+    warn "Could not find session desktop file $file";
+    return;
+  }
+
+  if (!open(IN, $file)) {
+    warn "Could not open session desktop file $file";
+    return;
+  }
+
+  $found_group = 0;
+  while (my $line = <IN>) {
+    next if $line =~ /^#/;
+    next if $line =~ /^\s*$/;
+
+    if (!$found_group) {
+        next if $line != "[Desktop Entry]";
+        $found_group = 1;
+        next;
+    } else {
+        last if $line =~ /^\[/;
+    }
+
+    my ($key, $value) = $line =~ /^\s*([]A-Za-z0-9_@\-\[]+)\s*=\s*(.*)$/;
+    if (!$key) {
+        warn "Invalid session desktop file $file";
+        close(IN);
+        return;
+    }
+
+    $value =~ s/\\s/ /g;
+    $value =~ s/\\n/\n/g;
+    $value =~ s/\\t/\t/g;
+    $value =~ s/\\r/\r/g;
+    $value =~ s/\\\\/\\/g;
+
+    $session{$key} = $value;
+  }
+
+  close(IN);
+
+  return %session;
+}
+
 #
 # CheckDisplayNumber checks if the given display number is available.  A
 # display number n is taken if something is listening on the VNC server port
@@ -496,8 +542,6 @@ sub Usage
     die("\nusage: $prog [:<number>]\n".
        "                 [-fg]\n".
        "                 [-autokill]\n".
-       "                 [-noxstartup]\n".
-       "                 [-xstartup <file>]\n".
        "\n".
        "       $prog -kill <X-display>\n\n".
        "       $prog -list\n\n");
@@ -653,6 +697,16 @@ sub SanityCheck
        die "$prog: couldn't find \"$cmd\" on your PATH.\n";
     }
 
+    foreach $cmd ("/etc/X11/xinit/Xsession", "/etc/X11/Xsession") {
+        if (-x "$cmd") {
+            $Xsession = $cmd;
+            last;
+        }
+    }
+    if (not defined $Xsession) {
+        die "$prog: Couldn't find suitable Xsession.\n";
+    }
+
     if($exedir eq "") {
       cmd2:
        foreach $cmd ("Xvnc","vncpasswd") {
index 9ae4318582770203a60f046d7456b608eabc3935..f8ce77d5cb1df895225bc33547a9d6606a353bc0 100644 (file)
@@ -6,9 +6,6 @@ vncserver \- start or stop a VNC server
 .RI [: display# ]
 .RB [ \-fg ]
 .RB [ \-autokill ]
-.RB [ \-noxstartup ]
-.RB [ \-xstartup 
-.IR script ]
 .br
 .BI "vncserver \-kill :" display#
 .br
@@ -33,9 +30,6 @@ available.  For example:
 vncserver :13
 .RE
 
-Editing the file $HOME/.vnc/xstartup allows you to change the applications run
-at startup (but note that this will not affect an existing VNC session.)
-
 .SH OPTIONS
 You can get a list of options by passing \fB\-h\fP as an option to vncserver.
 
@@ -46,8 +40,8 @@ killing the Xvnc process, whose process ID is stored in the file
 "$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid".  The
 .B \-kill
 option ignores anything preceding the first colon (":") in the display
-argument.  Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the
-end of your xstartup file after a particular application exits.
+argument.  Thus, you can invoke "vncserver \-kill $DISPLAY", for example
+inside your session to terminate it.
 .
 .TP
 .B \-fg
@@ -58,19 +52,8 @@ when launching TigerVNC from within certain grid computing environments.
 .
 .TP
 .B \-autokill
-Automatically kill Xvnc whenever the xstartup script exits.  In most cases,
-this has the effect of terminating Xvnc when the user logs out of the window
-manager.
-.
-.TP
-.B \-noxstartup
-Do not run the %HOME/.vnc/xstartup script after launching Xvnc.  This
-option allows you to manually start a window manager in your TigerVNC session.
-.
-.TP
-.B \-xstartup \fIscript\fP
-Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching
-Xvnc. This is useful to run full-screen applications.
+Automatically kill Xvnc whenever the session exits.  In most cases, this has
+the effect of terminating Xvnc when the user logs out of the window manager.
 .
 .TP
 .B \-list
@@ -79,11 +62,6 @@ Lists all VNC desktops started by vncserver.
 .SH FILES
 Several VNC-related files are found in the directory $HOME/.vnc:
 .TP
-$HOME/.vnc/xstartup
-A shell script specifying X applications to be run when a VNC desktop is
-started.  If this file does not exist, then vncserver will create a default
-xstartup script which attempts to launch your chosen window manager.
-.TP
 /etc/tigervnc/vncserver-config-defaults
 The optional system-wide equivalent of $HOME/.vnc/config. If this file exists
 and defines options to be passed to Xvnc, they will be used as defaults for
@@ -109,12 +87,18 @@ one per line. For those requiring an argument, simply separate the option from
 the argument with an equal sign, for example: "geometry=2000x1200" or
 "securitytypes=vncauth,tlsvnc". Options without an argument are simply listed
 as a single word, for example: "localhost" or "alwaysshared".
+
+The special option
+.B session
+can be used to control which session type will be started. This should match
+one of the files in \fI/usr/share/xsessions\fP. E.g. if there is a file called
+"gnome.desktop", then "session=gnome" would be set to use that session type.
 .TP
 $HOME/.vnc/passwd
 The VNC password file.
 .TP
 $HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log
-The log file for Xvnc and applications started in xstartup.
+The log file for Xvnc and the session.
 .TP
 $HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid
 Identifies the Xvnc process ID, used by the