xpra icon
Bug tracker and wiki

Opened 6 years ago

Closed 4 years ago

Last modified 14 months ago

#489 closed enhancement (fixed)

Allow sending a single application window

Reported by: danzza Owned by: alas
Priority: minor Milestone: 0.16
Component: server Version:
Keywords: Cc:

Description (last modified by Antoine Martin)

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.

Attachments (4)

choose-windows-by-pid.patch (2.3 KB) - added by Antoine Martin 4 years ago.
hacked patch to only show certain windows
ticket489_browser-displayed-off-center-after-being-resized-by-another-sharee.png (198.1 KB) - added by alas 4 years ago.
browser resized to larger by other session sharee - content displaying off center
ticket489_browser-re-centered-after-moving.png (257.4 KB) - added by alas 4 years ago.
same browser resized by sharee, but resized contents centered (and interactable) after moving
ticket489_semi-severe-case-of-browser-resized-smaller-by-sharee.png (172.0 KB) - added by alas 4 years ago.
semi-sever case of display of window when sharee sessions resizes to make smaller

Download all attachments as: .zip

Change History (25)

comment:1 Changed 6 years ago by danzza

Component: androidserver
Priority: majorminor

comment:2 Changed 6 years ago by Antoine Martin

Description: modified (diff)
Milestone: never

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.

comment:3 Changed 5 years ago by 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)

comment:4 Changed 4 years ago by Antoine Martin

Status: newassigned

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.

Last edited 4 years ago by Antoine Martin (previous) (diff)

Changed 4 years ago by Antoine Martin

Attachment: choose-windows-by-pid.patch added

hacked patch to only show certain windows

comment:5 Changed 4 years ago by Antoine Martin

Milestone: never0.16

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:

  • start a server with an xterm and sharing enabled:
    xpra start :10 --no-daemon --bind-tcp=0.0.0.0:10000 --start-child=xterm --sharing
    
  • connect a client with sharing enabled: xpra attach --sharing
  • find the pid of the xterm, and the uuid of the client:
    xpra info | egrep "uuid|pid"
    
  • tell the server to only send this pid to the client from then on (values are taken from the command above):
    xpra control :10 restrict THEVERYLONGUUIDVALUE PID
    
  • connect another client: xpra attach --sharing
  • start a new command in this session (either from a terminal, or using xpra control, or using the start-command menu entry in the system tray) - the new window should only be shown to the "unrestricted" client. (works for the windows and its drop down menu children, as long as the application sets the pid - they seem to)

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)

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:6 Changed 4 years ago by aradtech

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

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:7 Changed 4 years ago by Antoine Martin

Duplicate: #943.

comment:8 Changed 4 years ago by 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.

comment:9 Changed 4 years ago by 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:

  • regular window properties, ie: PID=9999 :
    "window", "pid", "=", Variant("i", 9999)
    
  • X11 properties:
    "x11window", "_XPRA_WID", "=", Variant("i", 2)
    

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)

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:10 Changed 4 years ago by 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)

comment:11 Changed 4 years ago by 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.

comment:12 Changed 4 years ago by 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.

comment:13 Changed 4 years ago by Antoine Martin

Owner: changed from Antoine Martin to alas
Status: assignednew

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)

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:14 Changed 4 years ago by 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.

comment:15 Changed 4 years ago by 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

comment:16 Changed 4 years ago by 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:

  • I launched two firefox windows with the shared box, then two more with the shared box unchecked... but the two launched with the box unchecked were also shared. Maybe firefox windows are all running as part of the same process, so they're shared because the initial process was shared?
  • gedit also seemed to be disinclined to open multiple windows, opening a second seemed to just replace the first.

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
  • While content typed into xterms is seen on both shared sessions, resizing seems to be independent between client sessions. With applications like chromium, however, resizing by one client seems to be reflected in the content on other shared sessions, while the "frame sizing" is not reflected, until the client not doing resizing interacts with the application (I'll create another ticket with some screenshots and steps to see if there's anything to deal with).

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

comment:17 Changed 4 years ago by 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.

Last edited 4 years ago by Antoine Martin (previous) (diff)

comment:18 Changed 4 years ago by 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.

  • xterms, when resized by one user, will change the displayed contents of the window for the other user(s) - looking a lot like the window is scrolling itself but without any change in the sizing of the window chrome.
  • browsers (firefox, chromium, others I expect as well), when resized by one user, will trigger a re-sizing of the window contents of the window for other user(s) - initially. If the user on the smaller sized window then interacts with the window, the user with the larger sized (presumably the one who started the confusion by re-sizing the shared window) will then see a re-painted browser "overlaid" over the old painted browser on the desktop... though the resizing will also sometimes (with a dual monitor setup) trigger a relocation of the browser (which, in several cases, fooled me into thinking that the browser had crashed on one of the shared sessions, without crashing on the other).

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.)


  • And, just as a note, as suggested in comment:4, it does indeed seem like only the initial client connection has a clipboard that syncs with the local clipboard - though other sharees do seem to be able to copy/paste within the session.


Changed 4 years ago by alas

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

Changed 4 years ago by alas

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

Changed 4 years ago by alas

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

comment:19 Changed 4 years ago by 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 Running more than one Firefox Profile at once? (see also 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.

comment:20 Changed 4 years ago by J. Max Mena

Resolution: fixed
Status: newclosed

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:

  • Started a session with xpra start :13 --bind-tcp=0.0.0.0:2200 --start-child=xterm --start-child=firefox --start-new-commands=yes --sharing
  • and connected from both a Windows and a Fedora 23 client with xpra attach tcp:$serverIP --sharing (of course in Windows it's Xpra_cmd.exe

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.

comment:21 Changed 14 months ago by Antoine Martin

Follow up: #1934.

Note: See TracTickets for help on using tickets.