diff --git a/src/xpra/darwin/gui.py b/src/xpra/darwin/gui.py index e7ffb96950..40781dfa82 100644 --- a/src/xpra/darwin/gui.py +++ b/src/xpra/darwin/gui.py @@ -18,7 +18,6 @@ def __init__(self, client, opts): self.locate_icon_filename(opts.tray_icon) self.setup_growl(opts.notifications) self.setup_macdock() - self.clipboard_helper = None def setup_growl(self, enabled): self.growl_notifier = None diff --git a/src/xpra/platform/client_extras_base.py b/src/xpra/platform/client_extras_base.py index f78d91d9e1..c4a5c33ffc 100644 --- a/src/xpra/platform/client_extras_base.py +++ b/src/xpra/platform/client_extras_base.py @@ -106,6 +106,7 @@ def __init__(self, client, opts): self.about_dialog = None self.tray_icon = opts.tray_icon self.session_name = opts.session_name + self.clipboard_helper = None self.set_window_icon(opts.window_icon) def set_window_icon(self, window_icon): @@ -670,7 +671,7 @@ def set_notifications_menuitem(*args): self.client.connect("handshake-complete", set_notifications_menuitem) return self.notifications_menuitem - def make_clipboardmenuitem(self): + def make_clipboard_togglemenuitem(self): def clipboard_toggled(*args): self.client.clipboard_enabled = self.clipboard_menuitem.get_active() log.debug("clipboard_toggled(%s) clipboard_enabled=%s", args, self.client.clipboard_enabled) @@ -688,6 +689,58 @@ def set_clipboard_menuitem(*args): self.client.connect("handshake-complete", set_clipboard_menuitem) return self.clipboard_menuitem + def make_translatedclipboard_optionsmenuitem(self): + clipboard_menu = self.menuitem("Clipboard", "clipboard.png", "Choose which remote clipboard to connect to", None) + clipboard_submenu = gtk.Menu() + clipboard_menu.set_submenu(clipboard_submenu) + self.popup_menu_workaround(clipboard_submenu) + def set_clipboard_menu(*args): + c = self.client + can_clipboard = c.server_supports_clipboard and c.client_supports_clipboard + log("set_clipboard_menu(%s) can_clipboard=%s, server=%s, client=%s", args, can_clipboard, c.server_supports_clipboard, c.client_supports_clipboard) + clipboard_menu.set_sensitive(can_clipboard) + LABEL_TO_NAME = {"Disabled" : None, + "Clipboard" : "CLIPBOARD", + "Primary" : "PRIMARY", + "Secondary" : "SECONDARY"} + for label, remote_clipboard in LABEL_TO_NAME.items(): + clipboard_item = CheckMenuItem(label) + def remote_clipboard_changed(item): + item = ensure_item_selected(clipboard_submenu, item) + label = item.get_label() + remote_clipboard = LABEL_TO_NAME.get(label) + old_state = self.client.clipboard_enabled + if remote_clipboard: + self.clipboard_helper.remote_clipboard = remote_clipboard + new_state = True + else: + new_state = False + log("remote_clipboard_changed(%s) label=%s, remote_clipboard=%s, old_state=%s, new_state=%s", + item, label, remote_clipboard, old_state, new_state) + if new_state!=old_state: + self.client.clipboard_enabled = new_state + self.client.emit("clipboard-toggled") + if new_state: + self.clipboard_helper.send_all_tokens() + clipboard_item.set_active(self.clipboard_helper.remote_clipboard==remote_clipboard) + clipboard_item.set_sensitive(can_clipboard) + clipboard_item.set_draw_as_radio(True) + clipboard_item.connect("toggled", remote_clipboard_changed) + clipboard_submenu.append(clipboard_item) + clipboard_submenu.show_all() + self.client.connect("handshake-complete", set_clipboard_menu) + return clipboard_menu + + def make_clipboardmenuitem(self): + try: + from xpra.platform.gdk_clipboard import TranslatedClipboardProtocolHelper + if self.clipboard_helper and isinstance(self.clipboard_helper, TranslatedClipboardProtocolHelper): + return self.make_translatedclipboard_optionsmenuitem() + except: + log.error("make_clipboardmenuitem()", exc_info=True) + return self.make_clipboard_togglemenuitem() + + def make_keyboardsyncmenuitem(self): def set_keyboard_sync_tooltip(): if not self.client.toggle_keyboard_sync: diff --git a/src/xpra/win32/gui.py b/src/xpra/win32/gui.py index 3d4f85048d..ddb221a708 100644 --- a/src/xpra/win32/gui.py +++ b/src/xpra/win32/gui.py @@ -10,6 +10,7 @@ from xpra.deque import maxdeque from xpra.platform.client_extras_base import ClientExtrasBase, WIN32_LAYOUTS +from xpra.platform.clipboard_base import DefaultClipboardProtocolHelper from xpra.keys import get_gtk_keymap from wimpiggy.log import Logger log = Logger() @@ -18,17 +19,15 @@ class ClientExtras(ClientExtrasBase): def __init__(self, client, opts): ClientExtrasBase.__init__(self, client, opts) - self.setup_menu() - self.setup_tray(opts.no_tray, opts.notifications, opts.tray_icon) - self._last_key_events = maxdeque(maxlen=5) - self._dropped_num_lock_press = False try: from xpra.platform.gdk_clipboard import TranslatedClipboardProtocolHelper self.setup_clipboard_helper(TranslatedClipboardProtocolHelper) except ImportError, e: log.error("GDK Translated Clipboard failed to load: %s - using default fallback", e) - from xpra.platform.clipboard_base import DefaultClipboardProtocolHelper self.setup_clipboard_helper(DefaultClipboardProtocolHelper) + self.setup_menu() + self.setup_tray(opts.no_tray, opts.notifications, opts.tray_icon) + self._last_key_events = maxdeque(maxlen=5) def exit(self): ClientExtrasBase.exit(self) diff --git a/src/xpra/xposix/gui.py b/src/xpra/xposix/gui.py index bfa5b7bd86..4caf042de7 100644 --- a/src/xpra/xposix/gui.py +++ b/src/xpra/xposix/gui.py @@ -16,6 +16,7 @@ assert _display, "cannot open the display with GTK, is DISPLAY set?" from xpra.platform.client_extras_base import ClientExtrasBase +from xpra.platform.clipboard_base import DefaultClipboardProtocolHelper from wimpiggy.log import Logger log = Logger() @@ -24,6 +25,12 @@ class ClientExtras(ClientExtrasBase): def __init__(self, client, opts): ClientExtrasBase.__init__(self, client, opts) + try: + from xpra.platform.gdk_clipboard import GDKClipboardProtocolHelper + self.setup_clipboard_helper(GDKClipboardProtocolHelper) + except ImportError, e: + log.error("GDK Clipboard failed to load: %s - using 'Default Clipboard' fallback", e) + self.setup_clipboard_helper(DefaultClipboardProtocolHelper) self.setup_menu(True) self.setup_tray(opts.no_tray, opts.tray_icon) self.setup_xprops(opts.pulseaudio) @@ -33,13 +40,6 @@ def __init__(self, client, opts): if opts.notifications: if not self.setup_dbusnotify() and not self.setup_pynotify(): log.error("turning notifications off") - try: - from xpra.platform.gdk_clipboard import GDKClipboardProtocolHelper - self.setup_clipboard_helper(GDKClipboardProtocolHelper) - except ImportError, e: - log.error("GDK Clipboard failed to load: %s - using 'Default Clipboard' fallback", e) - from xpra.platform.clipboard_base import DefaultClipboardProtocolHelper - self.setup_clipboard_helper(DefaultClipboardProtocolHelper) def exit(self): ClientExtrasBase.exit(self)