Skip to content

Commit

Permalink
#581 client request cleanup:
Browse files Browse the repository at this point in the history
* pass "exit_request" flag for "xpra exit"
* pass "detach_request" flag for "xpra detach"
* server will always detach all clients when "detach_request" is specified
* server can skip some setup functions when processing one of those requests

git-svn-id: https://xpra.org/svn/Xpra/trunk@6587 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed May 27, 2014
1 parent aa94895 commit 192248d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 47 deletions.
13 changes: 13 additions & 0 deletions src/xpra/client/gobject_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ class ExitXpraClient(CommandConnectClient):
def timeout(self, *args):
self.warn_and_quit(EXIT_TIMEOUT, "timeout: server did not disconnect us")

def make_hello(self):
capabilities = CommandConnectClient.make_hello(self)
capabilities["exit_request"] = True
return capabilities

def _process_hello(self, packet):
props = packet[1]
if not props.get("exit_server"):
Expand Down Expand Up @@ -280,6 +285,14 @@ def _process_hello(self, packet):
class DetachXpraClient(CommandConnectClient):
""" run the detach subcommand """

def make_hello(self):
#used for telling the proxy server we want "detach"
#(older versions ignore this flag and detach because this is a new valid connection
# but this breaks if sharing is enabled!)
capabilities = CommandConnectClient.make_hello(self)
capabilities["detach_request"] = True
return capabilities

def timeout(self, *args):
self.warn_and_quit(EXIT_TIMEOUT, "timeout: server did not disconnect us")

Expand Down
108 changes: 61 additions & 47 deletions src/xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,28 +471,37 @@ def hello_oked(self, proto, packet, c, auth_caps):
self.send_hello_info(proto)
return

#"normal" connection, so log welcome message:
log.info("Handshake complete; enabling connection")
detach_request = c.boolget("detach_request", False)
stop_request = c.boolget("stop_request", False)
exit_request = c.boolget("exit_request", False)
is_request = detach_request or stop_request or exit_request
if not is_request:
#"normal" connection, so log welcome message:
log.info("Handshake complete; enabling connection")

# Things are okay, we accept this connection, and may disconnect previous one(s)
share_count = 0
for p,ss in self._server_sources.items():
#check existing sessions are willing to share:
if not self.sharing:
if detach_request:
self.disconnect_client(p, "detach requested")
elif not self.sharing:
self.disconnect_client(p, "new valid connection received, this session does not allow sharing")
elif not c.boolget("share"):
self.disconnect_client(p, "new valid connection received, the new client does not wish to share")
elif not ss.share:
self.disconnect_client(p, "new valid connection received, this client had not enabled sharing ")
else:
share_count += 1
if share_count>0:
log.info("sharing with %s other client(s)", share_count)
self.dpi = c.intget("dpi", self.default_dpi)
if self.dpi>0:
#some non-posix clients never send us 'resource-manager' settings
#so just use a fake one to ensure the dpi gets applied:
self.update_server_settings({'resource-manager' : ""}, reset=(share_count==0))

if not is_request:
if share_count>0:
log.info("sharing with %s other client(s)", share_count)
self.dpi = c.intget("dpi", self.default_dpi)
if self.dpi>0:
#some non-posix clients never send us 'resource-manager' settings
#so just use a fake one to ensure the dpi gets applied:
self.update_server_settings({'resource-manager' : ""}, reset=(share_count==0))
#max packet size from client (the biggest we can get are clipboard packets)
proto.max_packet_size = 1024*1024 #1MB
proto.send_aliases = c.dictget("aliases")
Expand All @@ -517,7 +526,7 @@ def get_window_id(wid):
log("process_hello serversource=%s", ss)
ss.parse_hello(c)
dw, dh = None, None
if ss.desktop_size:
if ss.desktop_size and not is_request:
try:
dw, dh = ss.desktop_size
if not ss.screen_sizes:
Expand All @@ -528,46 +537,51 @@ def get_window_id(wid):
except:
dw, dh = None, None
self._server_sources[proto] = ss
root_w, root_h = self.set_best_screen_size()
self.calculate_workarea()
self.set_desktop_geometry(dw or root_w, dh or root_h)
#take the clipboard if no-one else has yet:
if ss.clipboard_enabled and self._clipboard_helper is not None and \
(self._clipboard_client is None or self._clipboard_client.is_closed()):
self._clipboard_client = ss
#deal with buggy win32 clipboards:
if "clipboard.greedy" not in c:
#old clients without the flag: take a guess based on platform:
client_platform = c.strget("platform", "")
greedy = client_platform.startswith("win") or client_platform.startswith("darwin")
else:
greedy = c.boolget("clipboard.greedy")
self._clipboard_helper.set_greedy_client(greedy)
want_targets = c.boolget("clipboard.want_targets")
self._clipboard_helper.set_want_targets_client(want_targets)
#the selections the client supports (default to all):
from xpra.platform.features import CLIPBOARDS
client_selections = c.strlistget("clipboard.selections", CLIPBOARDS)
log("process_hello server has clipboards: %s, client supports: %s", self._clipboards, client_selections)
self._clipboard_helper.enable_selections(client_selections)

#keyboard:
ss.keyboard_config = self.get_keyboard_config(c)

#so only activate this feature afterwards:
self.keyboard_sync = c.boolget("keyboard_sync", True)
key_repeat = c.intpair("key_repeat")
self.set_keyboard_repeat(key_repeat)

#always clear modifiers before setting a new keymap
ss.make_keymask_match(c.strlistget("modifiers", []))
self.set_keymap(ss)
if is_request:
root_w, root_h = self.get_root_window_size()
key_repeat = (0, 0)
else:
root_w, root_h = self.set_best_screen_size()
self.calculate_workarea()
self.set_desktop_geometry(dw or root_w, dh or root_h)
#take the clipboard if no-one else has yet:
if ss.clipboard_enabled and self._clipboard_helper is not None and \
(self._clipboard_client is None or self._clipboard_client.is_closed()):
self._clipboard_client = ss
#deal with buggy win32 clipboards:
if "clipboard.greedy" not in c:
#old clients without the flag: take a guess based on platform:
client_platform = c.strget("platform", "")
greedy = client_platform.startswith("win") or client_platform.startswith("darwin")
else:
greedy = c.boolget("clipboard.greedy")
self._clipboard_helper.set_greedy_client(greedy)
want_targets = c.boolget("clipboard.want_targets")
self._clipboard_helper.set_want_targets_client(want_targets)
#the selections the client supports (default to all):
from xpra.platform.features import CLIPBOARDS
client_selections = c.strlistget("clipboard.selections", CLIPBOARDS)
log("process_hello server has clipboards: %s, client supports: %s", self._clipboards, client_selections)
self._clipboard_helper.enable_selections(client_selections)

#keyboard:
ss.keyboard_config = self.get_keyboard_config(c)

#so only activate this feature afterwards:
self.keyboard_sync = c.boolget("keyboard_sync", True)
key_repeat = c.intpair("key_repeat")
self.set_keyboard_repeat(key_repeat)

#always clear modifiers before setting a new keymap
ss.make_keymask_match(c.strlistget("modifiers", []))
self.set_keymap(ss)

#send_hello will take care of sending the current and max screen resolutions
self.send_hello(ss, root_w, root_h, key_repeat, auth_caps)

# now we can set the modifiers to match the client
self.send_windows_and_cursors(ss)
if not is_request:
# now we can set the modifiers to match the client
self.send_windows_and_cursors(ss)

ss.startup_complete()

Expand Down

0 comments on commit 192248d

Please sign in to comment.