Xpra: Ticket #1835: clipboard synchronization with multiple clients

Follow up from #41, similar to #1716 which is for the keyboard.

To support the clipboard with multiple clients, we should be able to switch the clipboard owner automatically when we receive "active" events like mouse clicks and key presses. Probably not focus events since those fire too easily when moving windows or when they get focus automatically, etc. A dbus method to manually set and lock the clipboard owner could be useful too.

The non-active clients could still receive clipboard packet data, they just would not be able to claim the clipboard ownership and send data until the server decides to switch to them.

For backwards compatibility, we could just re-claim the clipboard whenever a non-active client tries to claim it. For newer clients, we should just tell them that they cannot claim it - possibly re-using the clipboard direction code by making the client aware of the server direction restrictions, see also #1329.



Sun, 27 May 2018 05:43:59 GMT - Antoine Martin: status changed

Made easier by #1838, see also #1312.


Mon, 18 Jun 2018 17:09:27 GMT - Antoine Martin: attachment set

switch clipboard driver automatically with user events (clicks, etc)


Wed, 20 Jun 2018 10:22:38 GMT - Antoine Martin: owner, status changed

Merged in r19670: mouse clicks and key events will switch the clipboard synchronization to that client connection. This can also be triggered via dbus SetUIDriver and the corresponding control channel command: r19671.

Notes:

@maxmylyn: ready for testing.


Mon, 02 Jul 2018 17:23:20 GMT - J. Max Mena: owner changed

I've tested a Fedora 28 trunk r19815 built from source client and a Win8.1 r19788 beta client against a Fedora 28 trunk r19815 server.

I've tested this for a couple hours using both, and I've only found one issue:

If I highlight some text and use control + c from the Windows client, and try to paste it into a local application (notepad), it does not seem to copy. Using the Right click -> Copy option works as expected.

Of note: The Fedora client works fine with control + c and using the Right click menu.

I'm not sure if that's a clipboard issue or if the keyboard event isn't firing. While watching -d clipboard logs - I do see the owner change whenever I switch clients (using two different client computers for this), but when I press control + c on the Windows client, I don't see the clipboard event like when I use the right click menu.

With -d keyboard (enabled via the control channel so I don't have to restart my server) I see the following events when control + c was pressed on the Windows client:

2018-07-02 10:19:58,555 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:19:58,556 get_keycode(67, c, ('control', 'mod2')) keyname+keycode lookup: 54
2018-07-02 10:19:58,556 process_key_action(['key-action', 14, 'c', True, ('control', 'mod2'), 99, '\x03', 67, 0]) server keycode=54
2018-07-02 10:19:58,556 make_keymask_match: ignored as keynames_for_mod not assigned yet
2018-07-02 10:19:58,556 handle_key(14,True,c,99,54,('control', 'mod2')) keyboard_sync=True
2018-07-02 10:19:58,557 is_modifier(54) not found
2018-07-02 10:19:58,557 handle keycode pressing    54: key 'c'
2018-07-02 10:19:58,557 fake_key(54, True)
2018-07-02 10:19:58,660 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:19:58,661 get_keycode(67, c, ('control', 'mod2')) keyname+keycode lookup: 54
2018-07-02 10:19:58,661 process_key_action(['key-action', 14, 'c', False, ('control', 'mod2'), 99, '\x03', 67, 0]) server keycode=54
2018-07-02 10:19:58,661 make_keymask_match: ignored as keynames_for_mod not assigned yet
2018-07-02 10:19:58,662 handle_key(14,False,c,99,54,('control', 'mod2')) keyboard_sync=True
2018-07-02 10:19:58,662 is_modifier(54) not found
2018-07-02 10:19:58,662 handle keycode unpressing  54: key 'c'
2018-07-02 10:19:58,662 fake_key(54, False)
2018-07-02 10:19:58,924 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:19:58,924 get_keycode(17, Control_L, ('mod2',)) keyname+keycode lookup: 37
2018-07-02 10:19:58,924 process_key_action(['key-action', 14, 'Control_L', False, ('mod2',), 65507, '', 17, 0]) server keycode=37
2018-07-02 10:19:58,924 make_keymask_match: ignored as keynames_for_mod not assigned yet
2018-07-02 10:19:58,925 handle_key(14,False,Control_L,65507,37,('mod2',)) keyboard_sync=True
2018-07-02 10:19:58,925 handle keycode 37: key Control_L was already unpressed, ignoring
2018-07-02 10:20:03,308 clear_keys_pressed()

Compare that to the Fedora client pressing control + c:

2018-07-02 10:21:41,006 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:21:41,006 get_keycode(37, Control_L, ('mod2',)) keyname lookup: 37
2018-07-02 10:21:41,006 process_key_action(['key-action', 14, 'Control_L', True, ('mod2',), 65507, '', 37, 0]) server keycode=37
2018-07-02 10:21:41,006 filtered_modifiers_set(['mod2'])=set(['mod2'])
2018-07-02 10:21:41,007 filtered_modifiers_set(('mod2',))=set(['mod2'])
2018-07-02 10:21:41,007 handle_key(14,True,Control_L,65507,37,('mod2',)) keyboard_sync=True
2018-07-02 10:21:41,007 handle keycode pressing    37: key 'Control_L'
2018-07-02 10:21:41,007 fake_key(37, True)
2018-07-02 10:21:42,355 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:21:42,355 get_keycode(54, c, ('control', 'mod2')) keyname lookup: 54
2018-07-02 10:21:42,356 process_key_action(['key-action', 14, 'c', True, ('control', 'mod2'), 99, '\x03', 54, 0]) server keycode=54
2018-07-02 10:21:42,356 filtered_modifiers_set(['control', 'mod2'])=set(['control', 'mod2'])
2018-07-02 10:21:42,357 filtered_modifiers_set(('control', 'mod2'))=set(['control', 'mod2'])
2018-07-02 10:21:42,357 handle_key(14,True,c,99,54,('control', 'mod2')) keyboard_sync=True
2018-07-02 10:21:42,357 is_modifier(54) not found
2018-07-02 10:21:42,357 handle keycode pressing    54: key 'c'
2018-07-02 10:21:42,358 fake_key(54, True)
2018-07-02 10:21:42,475 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:21:42,475 get_keycode(54, c, ('control', 'mod2')) keyname lookup: 54
2018-07-02 10:21:42,476 process_key_action(['key-action', 14, 'c', False, ('control', 'mod2'), 99, '\x03', 54, 0]) server keycode=54
2018-07-02 10:21:42,476 filtered_modifiers_set(['control', 'mod2'])=set(['control', 'mod2'])
2018-07-02 10:21:42,476 filtered_modifiers_set(('control', 'mod2'))=set(['control', 'mod2'])
2018-07-02 10:21:42,477 handle_key(14,False,c,99,54,('control', 'mod2')) keyboard_sync=True
2018-07-02 10:21:42,477 is_modifier(54) not found
2018-07-02 10:21:42,477 handle keycode unpressing  54: key 'c'
2018-07-02 10:21:42,477 fake_key(54, False)
2018-07-02 10:21:42,516 set_keyboard_layout_group(0) config=KeyboardConfig(us /  / None), current keyboard group=0
2018-07-02 10:21:42,516 get_keycode(37, Control_L, ('control', 'mod2')) keyname lookup: 37
2018-07-02 10:21:42,516 process_key_action(['key-action', 14, 'Control_L', False, ('control', 'mod2'), 65507, '', 37, 0]) server keycode=37
2018-07-02 10:21:42,516 modifier 'control' ignored (in ignored keynames=['Control_R', 'Control_L'])
2018-07-02 10:21:42,517 filtered_modifiers_set(['control', 'mod2'])=set(['mod2'])
2018-07-02 10:21:42,517 modifier 'control' ignored (in ignored keynames=['Control_R', 'Control_L'])
2018-07-02 10:21:42,517 filtered_modifiers_set(('control', 'mod2'))=set(['mod2'])
2018-07-02 10:21:42,517 handle_key(14,False,Control_L,65507,37,('control', 'mod2')) keyboard_sync=True
2018-07-02 10:21:42,517 handle keycode unpressing  37: key 'Control_L'
2018-07-02 10:21:42,518 fake_key(37, False)
2018-07-02 10:21:42,760 modifier 'mod2' ignored (in ignored keynames=['Num_Lock'])
---- Removed about thirty of the above line for cleanliness ----
2018-07-02 10:21:43,479 filtered_modifiers_set(('mod2',))=set([])
2018-07-02 10:21:44,202 clear_keys_pressed()

Mon, 02 Jul 2018 17:58:03 GMT - Antoine Martin: owner changed

If this control-c issue occurs without sharing enabled then it does not belong in this ticket. Please also specify the application used to test on the server side.


Mon, 02 Jul 2018 18:15:06 GMT - J. Max Mena:

Good point - looks like it's a Win client issue not a clipboard issue. I noticed in Chrome that keyboard shortcuts don't seem to work at all. I'll open a new ticket for that.

I used a few applications to test - mostly xfce4-terminal.


Fri, 14 Dec 2018 18:48:37 GMT - J. Max Mena: status changed; resolution set

Finally got around to testing this with a trunk r21228 Fedora 28 server, a trunk r21228 Fedora 28 client, and a 2.5 r21225 Win8 client.

Using xclip sharing functionality is working as expected. Closing.


Sat, 23 Jan 2021 05:35:02 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/1835