Xpra: Ticket #489: Allow sending a single application window

I would like WinSwitch to support sending one or a subset of windows from a single application to a remote client. This flexibility would allow, for example, one running instance of Firefox (which only allows one running instance per profile, oddly) with multiple windows on different displays.

My priority is to have this availability in the Xpra software on Linux.



Thu, 09 Jan 2014 17:18:45 GMT - danzza: priority, component changed


Fri, 10 Jan 2014 01:19:35 GMT - Antoine Martin: description changed; milestone set

This probably cannot work: how would we know which windows belong on one client and which ones belong on the other. This is more likely to cause pain and confusion, just for trying to workaround a specific application constraint (Firefox profiles).

Some background: every drop down menu, every dialog, every alert box, etc.. are all windows that we forward. Some of them set the "transient-for" attribute which allows us to link them back to their parent window, many do not.

In any case #41 would need to be finished first. And then the UI for managing this "feature" would be clumsy at best. I very much doubt we will ever get around to even trying to implement this ticket.


Mon, 19 May 2014 12:45:14 GMT - Antoine Martin:

Note: there is hope, someone requested the same feature on IRC recently. I suggested using the ---enable-sharing mode and overriding the can_send_window function to decide which windows are sent to whom. (not that I am volunteering to do the work)


Wed, 20 May 2015 11:17:27 GMT - Antoine Martin: status changed

Maybe we can implement this as an extension of what is required for #41: we will need to keep track of the window-state per client already, we can just have an extra flag or state for windows that are just not shown at all. (rather than say minimized)

We should also make the window actually minimized server side once all the clients have it minimized, so that the window state is as consistent as can be. (so the application knows when its window is not being shown at all, it may choose to change its UI elsewhere)

@sbennett: for your use-case, I think you will want one connection for clipboard + sound + bell + etc, and then one connection for each tab (without sound etc). Then you already know which tab has focus on the client side, so you can avoid raising any (new) windows that do not come through that connection.


Wed, 20 May 2015 11:17:53 GMT - Antoine Martin: attachment set

hacked patch to only show certain windows


Wed, 20 May 2015 11:23:17 GMT - Antoine Martin: milestone changed

With the proof-of-concept patch above, I can limit which windows are forwarded to a client by using the window's pid - which generally seems to be set for all windows, including transient O-R windows.

To use it:


We could quite easily tweak this code so that none of the windows are sent to any of the clients until we associate them with a specific client. (we are using the window pid as discriminator because that's easy to do, but we could also use the window class or whatever else is available)


Thu, 21 May 2015 17:01:21 GMT - aradtech:

Tried this out and it does indeed work :). (Very slight error in your instructions - edited comment:5)


Thu, 17 Sep 2015 03:36:28 GMT - Antoine Martin:

Duplicate: #943.


Fri, 25 Sep 2015 09:02:25 GMT - Antoine Martin:

We probably want to enhance the client start-new-command dialog to be able to specify that the application that gets started is (or isn't) restricted to this connection.

This grouping of windows is somewhat related to what we already do with "group-leader" (see r9707, #799) and how we deal with the taskbar and menus (see #228, #476, #472, #508). It makes sense to define a logical grouping similar to this, so we could then more easily tie the dbus org.gtk.Application API to it.


Tue, 06 Oct 2015 16:09:41 GMT - Antoine Martin:

Work in progress: generic code added in r10751 to enable us to do the filtering, includes a dbus interface (see #904).

The instructions below use the d-feet GUI tool on the /org/xpra/SourceNNNN session busname org.xpra.Source interface and AddWindowFilter method.

We can filter using:

etc..

For clarity, I use Variant in the instructions above, but to make things work you have to replace it with this horrible string instead: __import__('gi.repository.GLib', globals(), locals(), ['Variant']).Variant (found this magic incantation here: D-Bus D-Feet Send Dictionary of String,Variants in Python Syntax)


Wed, 07 Oct 2015 06:20:02 GMT - Antoine Martin:

As of r10753, we can start 'private' commands from the "launch new command" GUI. (available from the tray or from Alt+Shift+F2, as long as the "sharing" and "start-new-commands" options are enabled)

In order to do this sanely, the semantics of the filters have changed: filters are only applied if they evaluate to True and they will then restrict the window(s) they apply to to the source they are registered against.

In other words: requiring PID=9999 on Source1 (using commands as per comment:9) will restrict windows that advertise their PID as beeing 9999 to the client connection "Source1". No other clients will see those windows. (including newer clients that connect after the filter is added) Other windows which do not match PID=9999 will be shown to all clients unless other filters are added specifically for them.

I believe this gives us enough flexibility, without requiring a complicated interpretation of rules (ie: supporting "and" / "or" expressions, etc)


Sat, 10 Oct 2015 11:17:34 GMT - Antoine Martin:

Note: as of r10788, the client can specify a list of object_name, property_name, operator, value using the hello packet property window-filters. This allows the client to specify the filters before the end of the handshake.


Thu, 15 Oct 2015 00:56:08 GMT - alas:

Testing a little with 0.16.0 r10828 osx client against a 0.16.0 r10786 fedora 21 server, I'm running into issues with the steps from comment:5.

Trying the xpra control :10 restrict THEVERYLONGUUIDVALUE PID step, I'm getting an error code 6, apparently from the restrict command:

[tlaloc@jimador ~]$ xpra info :13 | egrep "uuid|pid"
child[0].pid=12974
child[1].pid=12927
child[2].pid=12925
child[3].pid=12921
client.speaker.pid=12974
client.uuid=0d6e0381698caeab50a41782fd9926b89542c346
server.pid=12878
window[1].pid=12927
window[2].pid=12925
window[3].pid=12989
[tlaloc@jimador ~]$ xpra control :13 restrict 0d6e0381698caeab50a41782fd9926b89542c346 12925
server returned error code 6
 invalid command
[tlaloc@jimador ~]$ xpra control :13 restrict 0d6e0381698caeab50a41782fd9926b89542c346 12989
server returned error code 6
 invalid command
[tlaloc@jimador ~]$ xpra control :13 restrict 0d6e0381698caeab50a41782fd9926b89542c346 window=12989
server returned error code 6
 invalid command
[tlaloc@jimador ~]$ xpra control :13 restrict
server returned error code 6
 invalid command

I may have been jumping the gun, but I also tried the above steps with encryption and password and encryption key in place, and trying the xpra info | egrep "uuid|pid" step failed with a traceback:

[tlaloc@jimador ~]$ xpra info :13 | egrep "uuid|pid" --password-file=password --encryption-keyfile=key --encryption=AES
grep: unrecognized option '--password-file=password'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
Traceback (most recent call last):
  File "/usr/lib64/python2.7/logging/__init__.py", line 883, in emit
    self.flush()
  File "/usr/lib64/python2.7/logging/__init__.py", line 843, in flush
    self.stream.flush()
IOError: [Errno 32] Broken pipe
Logged from file log.py, line 100
Traceback (most recent call last):
  File "/usr/lib64/python2.7/logging/__init__.py", line 883, in emit
    self.flush()
  File "/usr/lib64/python2.7/logging/__init__.py", line 843, in flush
    self.stream.flush()
IOError: [Errno 32] Broken pipe
Logged from file log.py, line 100

The server output (which might possibly be useful) was:

2015-10-14 17:28:38,117 New unix-domain connection received on /home/tlaloc/.xpra/jimador.spikes.eng-13
2015-10-14 17:28:38,117 receiving data using AES encryption
2015-10-14 17:28:38,172 New unix-domain connection received on /home/tlaloc/.xpra/jimador.spikes.eng-13
2015-10-14 17:28:38,172 receiving data using AES encryption
2015-10-14 17:28:38,229 Connection lost
2015-10-14 17:28:38,229 Disconnecting client '/home/tlaloc/.xpra/jimador.spikes.eng-13':
2015-10-14 17:28:38,230  unencrypted packet dropped
2015-10-14 17:28:38,235 Connection lost

Sharing the session is working as expected, but I couldn't think of any other means to restrict windows to a user/client id other than the control channel.


Thu, 15 Oct 2015 04:41:41 GMT - Antoine Martin: owner, status changed

I'm running into issues with the steps from comment:5.


The instructions in comment:5 referred to an experimental proof of concept patch which is not what got merged into the code base.


[tlaloc@jimador ~]$ xpra info :13 | egrep "uuid|pid" --password-file=password --encryption-keyfile=key --encryption=AES


You are passing xpra arguments to the egrep command... never going to work.


Sharing the session is working as expected, but I couldn't think of any other means to restrict windows to a user/client id other than the control channel.


As per comment:10 : As of r10753, we can start 'private' commands from the "launch new command" GUI. (available from the tray or from Alt+Shift+F2, as long as the "sharing" and "start-new-commands" options are enabled)


Thu, 15 Oct 2015 17:49:20 GMT - alas:

Ahh... will retest with those clarifications.

Quick note - since the above makes it unclear if the restrict control channel command is meant to be removed after the end of POC, or if it is meant to be an alternative. Looked more closely at the server logs (I should always look more closely at the server logs) and noticed this:

2015-10-14 17:47:33,407 invalid command: 'restrict' (must be one of: suspend, help, encoding, focus, min-speed, sound-output, quality, start-child, compression, speed, auto-refresh, idle-timeout, start, min-quality, print, scaling, send-file, resume, encoder, scaling-control, key, ungrab, server-idle-timeout, name, refresh, client, workspace, debug, hello)

I'll assume that it is meant to be a disabled control command, but I thought I'd mention it to be sure.


Fri, 16 Oct 2015 01:50:24 GMT - Antoine Martin:

unclear if the restrict control channel command is meant to be removed after the end of POC...


Try this:

$ xpra control :10 help
control supports: suspend, help, encoding, focus, min-speed, sound-output, quality, start-child, compression, speed, auto-refresh, idle-timeout, start, min-quality, print, scaling, send-file, resume, encoder, scaling-control, key, ungrab, server-idle-timeout, name, refresh, client, workspace, debug, hello
$ xpra control :10 help encoding
control command 'encoding': picture encoding

Fri, 16 Oct 2015 02:13:22 GMT - alas:

Ok, re-testing some with 0.16.0 r10828 osx client (& 0.16.0 r10783 win client) against 0.16.0 r10854 fedora 21 server - I was able to get the expected uuid & pid values with xpra info :13 --password-file=password --encryption-keyfile=key --encryption=AES | egrep "uuid|pid".

I am also finding that I can successfully start commands from the "launch new command" (Run Command) prompt, with the applications being shared if the box is checked and not if the box isn't checked - except that some applications seem to have some unexpected quirks:

After a little while of abusing this functionality, I wasn't able to launch any new windows/applications on either of the two shared sessions, shared or not, and I lost all ability to get any focus/interactibility in any of the windows on either server (much like in #980, but unable to regain focus by moving windows between monitors, resizing, or any thing else I've thought of- and also can't close any on either client, shared or not).

For an idea of how many spawnings it took to reach this point, from the server logs:

2015-10-15 18:23:10,618 started command 'firefox' with pid 27094
GLib-GIO-Message: Using the 'memory' GSettings backend.  Your settings will not be saved or shared with other applications.
2015-10-15 18:23:22,261 started command 'firefox' with pid 27360
2015-10-15 18:23:22,400 child 'firefox' with pid 27360 has terminated
2015-10-15 18:23:34,471 started command 'firefox' with pid 27552
2015-10-15 18:23:34,698 child 'firefox' with pid 27552 has terminated
2015-10-15 18:23:58,964 started command 'firefox' with pid 27941
2015-10-15 18:23:59,265 child 'firefox' with pid 27941 has terminated
2015-10-15 18:24:20,484 started command 'gedit' with pid 28259
GLib-GIO-Message: Using the 'memory' GSettings backend.  Your settings will not be saved or shared with other applications.
2015-10-15 18:24:34,508 started command 'gedit' with pid 28413

Ohh... and I should've thought of just checking with the help to see what the expectation would be. Ooops.


Fri, 16 Oct 2015 02:19:10 GMT - Antoine Martin:

I launched two firefox windows with the shared box.. gedit also seemed to be disinclined to open multiple windows..


gedit and firefox will use the same process id (and even the same window with gedit), you can verify this with xprop. If you want to discriminate firefox windows, you cannot use the PID.


I lost all ability to get any focus/interactibility in any of the windows on either server..


There is only one focus, with multiple clients - you are likely to encounter issues.


Fri, 16 Oct 2015 23:55:08 GMT - alas:

If you want to discriminate firefox windows, you cannot use the PID.

I actually wasn't using the PID, since I didn't see a way to do so aside from the xpra control restrict ... mentioned above. I was using the Run Command GUI, unchecking the share box. I presume that that is just a quirk of the application behavior though, no matter the interface (and likewise suppose that it wouldn't be worth the effort to find a way around to discriminate against firefox windows - though, just for reference completeness, repeating with the first firefox launched as not-shared and launching a second as shared, the second is also not shared).

I have also been noticing that when windows are re-sized by one user, there are variable experiences for other user(s) sharing the session.

When the resizing by another shared session causes the browser to be repainted, it becomes non-responsive until the window is moved (or, ironically, resized again by another sharee) in order to cause it to be "locally repainted".

(I'll attach a couple of the more interesting screenshots of windows not-quite-repainted.)



Sat, 17 Oct 2015 00:01:35 GMT - alas: attachment set

browser resized to larger by other session sharee - content displaying off center


Sat, 17 Oct 2015 00:02:58 GMT - alas: attachment set

same browser resized by sharee, but resized contents centered (and interactable) after moving


Sat, 17 Oct 2015 00:07:14 GMT - alas: attachment set

semi-sever case of display of window when sharee sessions resizes to make smaller


Sat, 17 Oct 2015 05:57:51 GMT - Antoine Martin:

..I was using the Run Command GUI, unchecking the share box..


The GUI starts a new process and uses its PID. So we get the same result, as expected.


suppose that it wouldn't be worth the effort to find a way around to discriminate against firefox windows..


There are many other window attributes which can be used to discriminate, not least of which the window-id which is always unique. This most definitely works as tested in the examples above, but we cannot provide a nice GUI for it since there is no way to associate automatically "running firefox" with the new window that may or may not come up. Alternatively you can How do I run two isolated instances of firefox?), as this will create a new process.


xterms, when resized by one user, will change the displayed contents ... will trigger a re-sizing of the window contents of the window for other user...


There are going to be many issues when sharing windows, those do not belong in this ticket but rather in #41, some may be dealt with as part of #990


though other sharees do seem to be able to copy/paste within the session.


When everything happens on the server within the session, the clipboard contents never need to be transmitted to the client for the clipboard to work as expected.


Fri, 08 Apr 2016 17:54:50 GMT - J. Max Mena: status changed; resolution set

Closing at the behest of afarr after further testing.

as per comment:10 - the functionality of shift + alt + f2 works flawlessly when using sharing. (using a r12356 client and server)

NOTE for KDE users: KDE has the shortcut shift + alt + f2 reserved for opening web-links. You'll have to either disable it (System Settings > Keyboard Shortcuts) or use a different DE. ( I switched to XFCE which has no such shortcut reserved by default)

Steps tested:

Using the shortcut and menu option works fine, and I can easily spawn shared and non-shared applications. Barring the issues with the focus/sizing that belongs in another ticket, this one is quite overdue for closure.


Wed, 15 Aug 2018 06:08:00 GMT - Antoine Martin:

Follow up: #1934.


Sat, 23 Jan 2021 04:57:09 GMT - migration script:

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