Skip to content

Commit

Permalink
#275: let the server tell the client about its pending clipboard requ…
Browse files Browse the repository at this point in the history
…ests:

* new capability named "clipboard.notifications" which is only implemented by new clients
* server_base registers the new clipboard progress callback and forwards its value to clients that support the new feature
* ClientExtrasBase now keeps track of both local and remote clipboard requests as those are updated separately (one from the local clipboard code, the other by the new network packet)

git-svn-id: https://xpra.org/svn/Xpra/trunk@2850 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Feb 28, 2013
1 parent 2c31d9f commit eb5e8e9
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 8 deletions.
Binary file added src/win32/clipboard.ico
Binary file not shown.
1 change: 1 addition & 0 deletions src/xpra/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ def make_hello(self, challenge_response=None):
capabilities["compressible_cursors"] = True
capabilities["dpi"] = self.dpi
capabilities["clipboard"] = self.client_supports_clipboard
capabilities["clipboard.notifications"] = self.client_supports_clipboard
capabilities["notifications"] = self.client_supports_notifications
capabilities["cursors"] = self.client_supports_cursors
capabilities["bell"] = self.client_supports_bell
Expand Down
16 changes: 11 additions & 5 deletions src/xpra/platform/client_extras_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ def __init__(self, client, opts, conn):
self.tray_icon = opts.tray_icon
self.session_name = opts.session_name
self.clipboard_helper = None
self.local_clipboard_requests = 0
self.remote_clipboard_requests = 0
#modifier bits:
self.modifier_mappings = None #{'control': [(37, 'Control_L'), (105, 'Control_R')], 'mod1':
self.modifier_keys = {} #{"Control_L" : "control", ...}
Expand Down Expand Up @@ -175,17 +177,21 @@ def clipboard_send(*parts):
self.client.send(*parts)
else:
log("clipboard is disabled, not sending clipboard packet")
def clipboard_progress(requests):
log("clipboard_progress(%s)", requests)
if requests>0:
def clipboard_progress(local_requests, remote_requests):
log("clipboard_progress(%s, %s)", local_requests, remote_requests)
if local_requests is not None:
self.local_clipboard_requests = local_requests
if remote_requests is not None:
self.remote_clipboard_requests = remote_requests
n = self.local_clipboard_requests+self.remote_clipboard_requests
if n>0:
self.set_icon("clipboard")
self.set_tooltip("%s clipboard requests in progress" % requests)
self.set_tooltip("%s clipboard requests in progress" % n)
self.set_blinking(True)
else:
self.set_icon("xpra")
self.set_tooltip("Xpra")
self.set_blinking(False)

self.clipboard_helper = helperClass(clipboard_send, clipboard_progress)
def clipboard_toggled(*args):
log("clipboard_toggled enabled=%s, server_supports_clipboard=%s", self.client.clipboard_enabled, self.client.server_supports_clipboard)
Expand Down
10 changes: 8 additions & 2 deletions src/xpra/platform/clipboard_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ def _get_clipboard_from_remote_handler(self, proxy, selection, target):
loop = NestedMainLoop()
self._clipboard_outstanding_requests[request_id] = loop
if self.progress_cb:
self.progress_cb(len(self._clipboard_outstanding_requests))
self.progress_cb(len(self._clipboard_outstanding_requests), None)
self.send("clipboard-request", request_id, self.local_to_remote(selection), target)
result = loop.main(1 * 1000, 2 * 1000)
debug("get clipboard from remote result(%s)=%s", request_id, result)
del self._clipboard_outstanding_requests[request_id]
if self.progress_cb:
self.progress_cb(len(self._clipboard_outstanding_requests))
self.progress_cb(len(self._clipboard_outstanding_requests), None)
return result

def _clipboard_got_contents(self, request_id, dtype, dformat, data):
Expand Down Expand Up @@ -191,11 +191,17 @@ def _process_clipboard_contents_none(self, packet):
request_id = packet[1]
self._clipboard_got_contents(request_id, None, None, None)

def _process_clipboard_pending_requests(self, packet):
pending = packet[1]
if self.progress_cb:
self.progress_cb(None, pending)

_packet_handlers = {
"clipboard-token": _process_clipboard_token,
"clipboard-request": _process_clipboard_request,
"clipboard-contents": _process_clipboard_contents,
"clipboard-contents-none": _process_clipboard_contents_none,
"clipboard-pending-requests": _process_clipboard_pending_requests,
}

def process_clipboard_packet(self, packet):
Expand Down
7 changes: 6 additions & 1 deletion src/xpra/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def __init__(self, clobber, sockets, opts):
self._clipboard_helper = None
self._clipboard_client = None
if opts.clipboard:
self._clipboard_helper = GDKClipboardProtocolHelper(self.send_clipboard_packet)
self._clipboard_helper = GDKClipboardProtocolHelper(self.send_clipboard_packet, self.clipboard_progress)

self.compression_level = opts.compression_level
self.password_file = opts.password_file
Expand Down Expand Up @@ -742,6 +742,11 @@ def do_get_info(self, proto, server_sources, window_ids):
log("get_info took %s", time.time()-start)
return info

def clipboard_progress(self, local_requests, remote_requests):
assert self._clipboard_helper is not None
if self._clipboard_client and self._clipboard_client.clipboard_notifications:
log("sending clipboard-pending-requests=%s to %s", local_requests, self._clipboard_client)
self._clipboard_client.send("clipboard-pending-requests", local_requests)

def send_clipboard_packet(self, *parts):
assert self._clipboard_helper is not None
Expand Down
2 changes: 2 additions & 0 deletions src/xpra/server_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def __init__(self, protocol, get_transient_for,
self.randr_notify = False
self.named_cursors = False
self.clipboard_enabled = False
self.clipboard_notifications = False
self.share = False
self.desktop_size = None
self.screen_sizes = []
Expand Down Expand Up @@ -456,6 +457,7 @@ def parse_batch_int(value, varname):
self.send_notifications = capabilities.get("notifications", False)
self.randr_notify = capabilities.get("randr_notify", False)
self.clipboard_enabled = capabilities.get("clipboard", True)
self.clipboard_notifications = capabilities.get("clipboard.notifications", False)
self.share = capabilities.get("share", False)
self.desktop_size = capabilities.get("desktop_size")
self.set_screen_sizes(capabilities.get("screen_sizes"))
Expand Down

0 comments on commit eb5e8e9

Please sign in to comment.