Skip to content

Commit

Permalink
#1206: add "start-desktop" subcommand and xnest option to configure X…
Browse files Browse the repository at this point in the history
…nest or Xephyr, we then start all child commands against this display

git-svn-id: https://xpra.org/svn/Xpra/trunk@12697 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed May 27, 2016
1 parent 72d69d8 commit 138957f
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 42 deletions.
12 changes: 12 additions & 0 deletions src/etc/xpra/xpra.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,15 @@ xvfb = %(xvfb_command)s

# Does the xvfb command support the "-displayfd" argument?
displayfd = %(has_displayfd)s

# Nested display command:
# xnest = Xnest \
# -geometry 1600x1200+100+100 \
# -dpi 96 -nolisten tcp -noreset \
# -auth $XAUTHORITY
# xnest = Xephyr \
# +extension Composite \
# -screen 1600x1200x24+32 \
# -dpi 96 -nolisten tcp -noreset \
# -auth $XAUTHORITY
xnest = %(xnest_command)s
9 changes: 8 additions & 1 deletion src/man/xpra.1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ xpra \- viewer for remote, persistent X applications
.SH SYNOPSIS
.PD 0
.HP \w'xpra\ 'u
\fBxpra\fP \fBstart\fP [\fI:DISPLAY\fP] | \fBxpra\fP \fBstart\fP \fIssh:HOST:DISPLAY\fP
\fBxpra\fP \fBstart\fP [\fI:DISPLAY\fP] | \fBxpra\fP \fBstart\fP \fIssh:HOST:DISPLAY\fP |
\fBxpra\fP \fBstart-desktop\fP [\fI:DISPLAY\fP] | \fBxpra\fP \fBstart-desktop\fP \fIssh:HOST:DISPLAY\fP
[\fB\-\-start\fP=\fICOMMAND\fP]\fB .\|.\|.\fP
[\fB\-\-start\-child\fP=\fICOMMAND\fP]\fB .\|.\|.\fP
[\fB\-\-start\-after\-connect\fP=\fIyes\fP|\fIno\fP]
Expand Down Expand Up @@ -245,6 +246,9 @@ Start an xpra server using display number \fI:7\fP.
\fBxpra start\fP \fIssh:bigbox:7 \-\-start=xterm\fP
Start an xpra server on \fIbigbox\fP with an xterm in it,
and connect to it.
\fBxpra start-desktop \-\-start=xfce4-session\fP
Start an xfce session in a nested X11 server on an automatically
assigned display number.
.TP
\fBDISPLAY=\fP\fI:7 firefox\fP
Start \fIfirefox\fP running inside the xpra server. Run this on the host
Expand Down Expand Up @@ -349,6 +353,9 @@ number.)
This command starts a new xpra server, including any necessary setup.
(When starting a remote server with the \fBssh:HOST:DISPLAY\fP syntax,
the new session will also be attached.)
.SS xpra start-desktop
Starts a nested X11 server, all child commands will be started in the
nested X11 server.
.SS xpra attach
This command attaches to a running xpra server, and forwards any
applications using that server to appear on your current screen.
Expand Down
43 changes: 38 additions & 5 deletions src/xpra/client/gtk_base/client_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,16 +698,36 @@ def destroy(self, *args):
self.window = None
gtk.main_quit()

def update_options_from_URL(self, url):
from xpra.scripts.main import parse_URL
address, props = parse_URL(url)
pa = address.split(":")
if pa[0] in ("tcp", "ssh") and len(pa)>=2:
props["mode"] = pa
host = pa[1]
ph = host.split("@", 1)
if len(ph)==2:
username, host = ph
props["username"] = username
props["host"] = host
if len(pa)>=3:
props["port"] = pa[2]
self._apply_props(props)

def update_options_from_file(self, filename):
log("update_options_from_file(%s)", filename)
props = read_config(filename)
self._apply_props(props)

def _apply_props(self, props):
#we rely on "ssh_port" being defined on the config object
#so try to load it from file, and define it if not present:
options = validate_config(props, extras_types=LAUNCHER_OPTION_TYPES, extras_validation=self.get_launcher_validation())
for k,v in options.items():
fn = k.replace("-", "_")
setattr(self.config, fn, v)
self.config_keys = self.config_keys.union(set(props.keys()))
log("update_options_from_file(%s) populated config with keys '%s', ssh=%s", filename, options.keys(), self.config.ssh)
log("_apply_props(%s) populated config with keys '%s', ssh=%s", props, options.keys(), self.config.ssh)

def choose_session_file(self, title, action, action_button, callback):
file_filter = gtk.FileFilter()
Expand Down Expand Up @@ -816,9 +836,9 @@ def show_signal():
#maybe we should always run this code from the main loop instead
if sys.platform.startswith("darwin"):
#wait a little bit for the "openFile" signal
app.__osx_open_file = False
app.__osx_open_signal = False
def do_open_file(filename):
app.__osx_open_file = True
app.__osx_open_signal = True
app.update_options_from_file(filename)
#the compressors and packet encoders cannot be changed from the UI
#so apply them now:
Expand All @@ -829,11 +849,24 @@ def do_open_file(filename):
def open_file(_, filename):
log("open_file(%s)", filename)
glib.idle_add(do_open_file, filename)
def do_open_URL(url):
app.__osx_open_signal = True
app.update_options_from_URL(url)
#the compressors and packet encoders cannot be changed from the UI
#so apply them now:
configure_network(app.config)
app.update_gui_from_config()
if app.config.autoconnect:
glib.idle_add(app.do_connect)
def open_URL(_, url):
log("open_URL(%s)", url)
glib.idle_add(do_open_URL, url)
from xpra.platform.darwin.gui import get_OSXApplication
get_OSXApplication().connect("NSApplicationOpenURL", open_URL)
get_OSXApplication().connect("NSApplicationOpenFile", open_file)
def may_show():
log("may_show() osx open file=%s", app.__osx_open_file)
if not app.__osx_open_file:
log("may_show() osx open file=%s", app.__osx_open_signal)
if not app.__osx_open_signal:
app.show()
glib.timeout_add(500, may_show)
else:
Expand Down
16 changes: 16 additions & 0 deletions src/xpra/scripts/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ def get_Xvfb_command():
]
return cmd

def get_Xephyr_command():
cmd = ["Xephyr",
"+extension", "Composite",
"-screen", "1600x1200x24+32",
#better than leaving to vfb after a resize?
"-dpi", "96",
"-nolisten", "tcp",
"-noreset",
"-auth", "$XAUTHORITY"
]
return cmd


def OpenGL_safety_check():
#Ubuntu 12.04 will just crash on you if you try:
Expand Down Expand Up @@ -303,6 +315,7 @@ def read_xpra_defaults():
"mode" : str,
"ssh" : str,
"xvfb" : str,
"xnest" : str,
"socket-dir" : str,
"mmap" : str,
"log-dir" : str,
Expand Down Expand Up @@ -446,8 +459,10 @@ def get_defaults():
username = get_username()
except:
username = ""
xnest = get_Xephyr_command()
if WIN32 or PYTHON3:
xvfb = ""
xnest = ""
elif XDUMMY:
xvfb = get_Xdummy_command(use_wrapper=XDUMMY_WRAPPER, log_dir=get_default_log_dir())
else:
Expand Down Expand Up @@ -485,6 +500,7 @@ def addtrailingslash(v):
"tcp-encryption-keyfile": "",
"ssh" : DEFAULT_SSH_COMMAND,
"xvfb" : " ".join(xvfb),
"xnest" : " ".join(xnest),
"socket-dir" : "",
"log-dir" : get_default_log_dir(),
"log-file" : "$DISPLAY.log",
Expand Down
34 changes: 23 additions & 11 deletions src/xpra/scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,15 @@ def do_parse_cmdline(cmdline, defaults):
server_modes = []
if supports_server:
server_modes.append("start")
server_modes.append("start-desktop")
server_modes.append("upgrade")
#display: default to required
dstr = " DISPLAY"
if defaults.displayfd:
#display argument is optional (we can use "-displayfd")
dstr = " [DISPLAY]"
command_options = ["\t%prog start"+dstr+"\n",
"\t%prog start-desktop"+dstr+"\n",
"\t%prog stop [DISPLAY]\n",
"\t%prog exit [DISPLAY]\n",
"\t%prog list\n",
Expand Down Expand Up @@ -386,9 +388,15 @@ def ignore(defaults):
dest="fake_xinerama",
default=defaults.fake_xinerama,
help="Setup fake xinerama support for the session. Default: %s." % enabled_str(defaults.fake_xinerama))
group.add_option("--xnest", action="store",
dest="xnest",
default=defaults.xnest,
metavar="CMD",
help="How to run the nested X server. Default: '%default'.")
else:
ignore({"use-display" : False,
"xvfb" : '',
"xnest" : '',
"fake-xinerama" : defaults.fake_xinerama})
group.add_option("--resize-display", action="store",
dest="resize_display", default=defaults.resize_display, metavar="yes|no",
Expand Down Expand Up @@ -927,7 +935,7 @@ def configure_logging(options, mode):
to = sys.stderr
if mode in ("showconfig", "info", "control", "list", "attach", "stop", "version", "print", "opengl"):
to = sys.stdout
if mode in ("start", "upgrade", "attach", "shadow", "proxy", "_sound_record", "_sound_play", "stop", "print", "showconfig"):
if mode in ("start", "start-desktop", "upgrade", "attach", "shadow", "proxy", "_sound_record", "_sound_play", "stop", "print", "showconfig"):
if "help" in options.speaker_codec or "help" in options.microphone_codec:
info = show_sound_codec_help(mode!="attach", options.speaker_codec, options.microphone_codec)
raise InitInfo("\n".join(info))
Expand Down Expand Up @@ -999,16 +1007,16 @@ def run_mode(script_file, error_cb, options, args, mode, defaults):
#sound commands don't want to set the name
#(they do it later to prevent glib import conflicts)
#"attach" does it when it received the session name from the server
if mode not in ("attach", "start", "upgrade", "proxy", "shadow"):
if mode not in ("attach", "start", "start-desktop", "upgrade", "proxy", "shadow"):
from xpra.platform import set_name
set_name("Xpra", "Xpra %s" % mode.strip("_"))

try:
ssh_display = len(args)>0 and (args[0].startswith("ssh/") or args[0].startswith("ssh:"))
if mode in ("start", "shadow") and ssh_display:
if mode in ("start", "start-desktop", "shadow") and ssh_display:
#ie: "xpra start ssh:HOST:DISPLAY --start-child=xterm"
return run_remote_server(error_cb, options, args, mode, defaults)
elif (mode in ("start", "upgrade", "proxy") and supports_server) or (mode=="shadow" and supports_shadow):
elif (mode in ("start", "start-desktop", "upgrade", "proxy") and supports_server) or (mode=="shadow" and supports_shadow):
current_display = nox()
from xpra.scripts.server import run_server
return run_server(error_cb, options, mode, script_file, args, current_display)
Expand All @@ -1019,7 +1027,7 @@ def run_mode(script_file, error_cb, options, args, mode, defaults):
return run_stopexit(mode, error_cb, options, args)
elif mode == "list" and (supports_server or supports_shadow):
return run_list(error_cb, options, args)
elif mode in ("_proxy", "_proxy_start", "_shadow_start") and (supports_server or supports_shadow):
elif mode in ("_proxy", "_proxy_start", "_proxy_start_desktop", "_shadow_start") and (supports_server or supports_shadow):
nox()
return run_proxy(error_cb, options, script_file, args, mode, defaults)
elif mode in ("_sound_record", "_sound_play", "_sound_query"):
Expand Down Expand Up @@ -1643,9 +1651,10 @@ def run_remote_server(error_cb, opts, args, mode, defaults):
#and use _proxy_start subcommand:
if mode=="shadow":
params["proxy_command"] = ["_shadow_start"]
else:
assert mode=="start"
elif mode=="start":
params["proxy_command"] = ["_proxy_start"]
elif mode=="start-desktop":
params["proxy_command"] = ["_proxy_start_desktop"]
app = make_client(error_cb, opts)
app.init(opts)
app.init_ui(opts)
Expand Down Expand Up @@ -1726,12 +1735,15 @@ def run_glcheck(opts):
def run_proxy(error_cb, opts, script_file, args, mode, defaults):
from xpra.scripts.fdproxy import XpraProxy
no_gtk()
if mode in ("_proxy_start", "_shadow_start"):
if mode in ("_proxy_start", "_proxy_start_desktop", "_shadow_start"):
dotxpra = DotXpra(opts.socket_dir, opts.socket_dirs)
#we must use a subprocess to avoid messing things up - yuk
cmd = [script_file]
if mode=="_proxy_start":
cmd.append("start")
if mode in ("_proxy_start", "_proxy_start_desktop"):
if mode=="start":
cmd.append("start")
else:
cmd.append("start-desktop")
if len(args)==1:
display_name = args[0]
elif len(args)==0:
Expand All @@ -1741,7 +1753,7 @@ def run_proxy(error_cb, opts, script_file, args, mode, defaults):
display_name = 'S' + str(os.getpid())
existing_sockets = set(dotxpra.sockets(matching_state=dotxpra.LIVE))
else:
raise InitException("_proxy_start: expected 0 or 1 arguments but got %s: %s" % (len(args), args))
raise InitException("%s: expected 0 or 1 arguments but got %s: %s" % (mode, len(args), args))
else:
assert mode=="_shadow_start"
assert len(args) in (0, 1), "_shadow_start: expected 0 or 1 arguments but got %s: %s" % (len(args), args)
Expand Down
Loading

0 comments on commit 138957f

Please sign in to comment.