Skip to content

Commit

Permalink
#812 win32 native clipboard (not enabled yet), move common timer code…
Browse files Browse the repository at this point in the history
… to new helper class, implement text targets

git-svn-id: https://xpra.org/svn/Xpra/trunk@22404 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Apr 14, 2019
1 parent 8946929 commit af9fa28
Show file tree
Hide file tree
Showing 6 changed files with 450 additions and 89 deletions.
35 changes: 35 additions & 0 deletions src/tests/xpra/clipboard/test_clipboard_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python

from xpra.platform import program_context
from xpra.platform.win32.clipboard import Win32Clipboard, log

def main():
with program_context("Clipboard-Test", "Clipboard Test Tool"):
def send_packet_cb(*args):
print("send_packet_cb%s" % (args,))
def progress_cb(*args):
print("progress_cb%s" % (args,))
try:
log("creating %s", Win32Clipboard)
c = Win32Clipboard(send_packet_cb, progress_cb)
log("sending all tokens")
c.enable_selections(["CLIPBOARD"])
c.set_direction(True, True)
c.send_all_tokens()
log("faking clipboard request")
c._process_clipboard_request(["clipboard-request", 1, "CLIPBOARD", "TARGETS"])
def set_contents():
pass
#c._process_clipboard_token(["clipboard-token", "CLIPBOARD", ])
#_process_clipboard_contents(self, packet):
from xpra.gtk_common.gobject_compat import import_glib
glib = import_glib()
main_loop = glib.MainLoop()
glib.timeout_add(1000, set_contents)
log("main loop=%s", main_loop)
main_loop.run()
except:
log.error("", exc_info=True)

if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion src/xpra/clipboard/clipboard_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ def got_contents(dtype, dformat, data):
data = data[:max_send_datalen]
munged = self._munge_raw_selection_to_wire(target, dtype, dformat, data)
wire_encoding, wire_data = munged
log("clipboard raw -> wire: %r -> %r", (dtype, dformat, data), munged)
log("clipboard raw -> wire: %r -> %r",
(dtype, dformat, repr_ellipsized(str(data))), repr_ellipsized(str(munged)))
if wire_encoding is None:
no_contents()
return
Expand Down
109 changes: 109 additions & 0 deletions src/xpra/clipboard/clipboard_timeout_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# This file is part of Xpra.
# Copyright (C) 2019 Antoine Martin <antoine@xpra.org>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

from xpra.gtk_common.gobject_compat import import_glib
from xpra.clipboard.clipboard_core import ClipboardProtocolHelperCore
from xpra.util import repr_ellipsized, envint
from xpra.log import Logger
from xpra.platform.features import CLIPBOARD_GREEDY

glib = import_glib()

log = Logger("clipboard")

CONVERT_TIMEOUT = envint("XPRA_CLIPBOARD_CONVERT_TIMEOUT", 500)
REMOTE_TIMEOUT = envint("XPRA_CLIPBOARD_REMOTE_TIMEOUT", 1500)
assert 0<CONVERT_TIMEOUT<5000
assert 0<REMOTE_TIMEOUT<5000


class ClipboardTimeoutHelper(ClipboardProtocolHelperCore):

#a clipboard superclass that handle's timeouts
def __init__(self, send_packet_cb, progress_cb=None, **kwargs):
ClipboardProtocolHelperCore.__init__(self, send_packet_cb, progress_cb, **kwargs)
self._clipboard_outstanding_requests = {}

def cleanup(self):
#reply to outstanding requests with "no data":
for request_id in tuple(self._clipboard_outstanding_requests.keys()):
self._clipboard_got_contents(request_id)
self._clipboard_outstanding_requests = {}
ClipboardProtocolHelperCore.cleanup(self)

def _get_proxy(self, selection):
proxy = self._clipboard_proxies.get(selection)
if not proxy:
log.warn("Warning: no clipboard proxy for '%s'", selection)
return None
return proxy

def set_want_targets_client(self, want_targets):
ClipboardProtocolHelperCore.set_want_targets_client(self, want_targets)
#pass it on to the ClipboardProxy instances:
for proxy in self._clipboard_proxies.values():
proxy.set_want_targets(want_targets)


############################################################################
# network methods for communicating with the remote clipboard:
############################################################################
def _send_clipboard_token_handler(self, proxy, packet_data=()):
log("_send_clipboard_token_handler(%s, %s)", proxy, packet_data)
packet = ["clipboard-token", proxy._selection]
if packet_data:
#append 'TARGETS' unchanged:
packet.append(packet_data[0])
#if present, the next element is the target data,
#which we have to convert to wire format:
if len(packet_data)>=2:
target, dtype, dformat, data = packet_data[1]
wire_encoding, wire_data = self._munge_raw_selection_to_wire(target, dtype, dformat, data)
if wire_encoding:
wire_data = self._may_compress(dtype, dformat, wire_data)
if wire_data:
packet += [target, dtype, dformat, wire_encoding, wire_data]
claim = proxy._can_send
packet += [claim, CLIPBOARD_GREEDY]
self.send(*packet)

def _send_clipboard_request_handler(self, proxy, selection, target):
log("send_clipboard_request_handler%s", (proxy, selection, target))
request_id = self._clipboard_request_counter
self._clipboard_request_counter += 1
log("send_clipboard_request id=%s", request_id)
timer = glib.timeout_add(REMOTE_TIMEOUT, self.timeout_request, request_id)
self._clipboard_outstanding_requests[request_id] = (timer, selection, target)
self.progress()
self.send("clipboard-request", request_id, self.local_to_remote(selection), target)

def timeout_request(self, request_id):
try:
selection, target = self._clipboard_outstanding_requests.pop(request_id)[1:]
except KeyError:
log.warn("Warning: request id %i not found", request_id)
return
finally:
self.progress()
log.warn("Warning: remote clipboard request timed out")
log.warn(" request id %i, selection=%s, target=%s", request_id, selection, target)
proxy = self._get_proxy(selection)
if proxy:
proxy.got_contents(target)

def _clipboard_got_contents(self, request_id, dtype=None, dformat=None, data=None):
try:
timer, selection, target = self._clipboard_outstanding_requests.pop(request_id)
except KeyError:
log.warn("Warning: request id %i not found", request_id)
return
finally:
self.progress()
glib.source_remove(timer)
proxy = self._get_proxy(selection)
log("clipboard got contents%s: proxy=%s for selection=%s",
(request_id, dtype, dformat, repr_ellipsized(str(data))), proxy, selection)
if proxy:
proxy.got_contents(target, dtype, dformat, data)
Loading

0 comments on commit af9fa28

Please sign in to comment.