diff --git a/src/xpra/platform/client_extras_base.py b/src/xpra/platform/client_extras_base.py index 53347aabb3..781eb778fc 100644 --- a/src/xpra/platform/client_extras_base.py +++ b/src/xpra/platform/client_extras_base.py @@ -175,7 +175,18 @@ def clipboard_send(*parts): self.client.send(*parts) else: log("clipboard is disabled, not sending clipboard packet") - self.clipboard_helper = helperClass(clipboard_send) + def clipboard_progress(requests): + log("clipboard_progress(%s)", requests) + if requests>0: + self.set_icon("clipboard") + self.set_tooltip("%s clipboard requests in progress" % requests) + 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) if self.client.clipboard_enabled and self.client.server_supports_clipboard: diff --git a/src/xpra/platform/clipboard_base.py b/src/xpra/platform/clipboard_base.py index f84809c88a..97d23cbd61 100644 --- a/src/xpra/platform/clipboard_base.py +++ b/src/xpra/platform/clipboard_base.py @@ -16,7 +16,6 @@ else: PROPERTY_CHANGE_MASK = gdk.PROPERTY_CHANGE_MASK - from wimpiggy.util import n_arg_signal from wimpiggy.log import Logger log = Logger() @@ -27,10 +26,14 @@ #debug = log.info debug = log.debug +MAX_CLIPBOARD_PACKET_SIZE = 256*1024 + + class ClipboardProtocolHelperBase(object): - def __init__(self, send_packet_cb, clipboards=["CLIPBOARD"]): + def __init__(self, send_packet_cb, progress_cb=None, clipboards=["CLIPBOARD"]): self.send = send_packet_cb - self.max_clipboard_packet_size = 32*1024 - 1024 + self.progress_cb = progress_cb + self.max_clipboard_packet_size = MAX_CLIPBOARD_PACKET_SIZE self._clipboard_proxies = {} for clipboard in clipboards: proxy = ClipboardProxy(clipboard) @@ -66,10 +69,14 @@ def _get_clipboard_from_remote_handler(self, proxy, selection, target): debug("get clipboard from remote handler id=%s", request_id) loop = NestedMainLoop() self._clipboard_outstanding_requests[request_id] = loop + if self.progress_cb: + self.progress_cb(len(self._clipboard_outstanding_requests)) 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)) return result def _clipboard_got_contents(self, request_id, dtype, dformat, data): @@ -162,7 +169,8 @@ def no_contents(): if len(wire_data)>256: wire_data = zlib_compress("clipboard: %s / %s" % (dtype, dformat), wire_data) if len(wire_data)>self.max_clipboard_packet_size: - log.warn("even compressed, clipboard contents are too big and have not been sent: %s compressed bytes dropped" % len(wire_data)) + log.warn("even compressed, clipboard contents are too big and have not been sent:" + " %s compressed bytes dropped (maximum is %s)", len(wire_data), self.max_clipboard_packet_size) no_contents() return self.send("clipboard-contents", request_id, selection, @@ -202,8 +210,8 @@ class DefaultClipboardProtocolHelper(ClipboardProtocolHelperBase): But without gdk atom support, see gdk_clipboard for a better one! """ - def __init__(self, send_packet_cb): - ClipboardProtocolHelperBase.__init__(self, send_packet_cb, ["CLIPBOARD", "PRIMARY", "SECONDARY"]) + def __init__(self, send_packet_cb, progress_cb=None): + ClipboardProtocolHelperBase.__init__(self, send_packet_cb, progress_cb, ["CLIPBOARD", "PRIMARY", "SECONDARY"]) class ClipboardProxy(gtk.Invisible): diff --git a/src/xpra/platform/gdk_clipboard.py b/src/xpra/platform/gdk_clipboard.py index 2bd88c5d5e..b8793c877c 100644 --- a/src/xpra/platform/gdk_clipboard.py +++ b/src/xpra/platform/gdk_clipboard.py @@ -19,8 +19,8 @@ class GDKClipboardProtocolHelper(ClipboardProtocolHelperBase): to and from a form suitable for transport over the wire. """ - def __init__(self, send_packet_cb): - ClipboardProtocolHelperBase.__init__(self, send_packet_cb, ["CLIPBOARD", "PRIMARY", "SECONDARY"]) + def __init__(self, send_packet_cb, progress_cb=None): + ClipboardProtocolHelperBase.__init__(self, send_packet_cb, progress_cb, ["CLIPBOARD", "PRIMARY", "SECONDARY"]) def _do_munge_raw_selection_to_wire(self, target, datatype, dataformat, data): if dataformat == 32 and datatype in ("ATOM", "ATOM_PAIR"): @@ -65,10 +65,10 @@ class TranslatedClipboardProtocolHelper(GDKClipboardProtocolHelper): and we generally want to map it to X11's "PRIMARY"... """ - def __init__(self, send_packet_cb, local_clipboard="CLIPBOARD", remote_clipboard="PRIMARY"): + def __init__(self, send_packet_cb, progress_cb=None, local_clipboard="CLIPBOARD", remote_clipboard="PRIMARY"): self.local_clipboard = local_clipboard self.remote_clipboard = remote_clipboard - ClipboardProtocolHelperBase.__init__(self, send_packet_cb, [local_clipboard]) + ClipboardProtocolHelperBase.__init__(self, send_packet_cb, progress_cb, [local_clipboard]) def local_to_remote(self, selection): debug("local_to_remote(%s) local_clipboard=%s, remote_clipboard=%s", selection, self.local_clipboard, self.remote_clipboard)