[RFC wayland-protocols] unstable: add protocol to give focus to a foreign surface

raof at ubuntu.com raof at ubuntu.com
Fri Jul 6 02:38:15 UTC 2018



On Fri, Jul 6, 2018 at 1:26 AM, David Edmundson 
<david at davidedmundson.co.uk> wrote:
> This protocol is to address the following use case.
> 
> A user clicks on a URL link in an IRC chat and a web browser opens. 
> We want an existing browser window to raise or if it's a newly 
> spawned application to claim focus on startup.
> 
> Naturally we also don't want any arbitrary client to be able to raise 
> themselves arbitrarily.
> 
> The protocol is a combination of xdg-foreign and some very simplified 
> aspects of X's startup-notification.
> 
> In the example above, the chat client gets a token from the 
> compositor and passes it to the browser using:
>   - an environment variable for newly spawned apps
>   - platofrm-hints in the org.freedesktop.Application interface
>   - some hint in the relevant xdg-portal interface
>   - any custom mechanism
> 
> The browser then requests a raise of a top-level using this token.
> 
> (Exact common mechanisms should probably be defined, but maybe not in 
> this document)
> 
> The exporter is virtually identical to xdg-foreign's exporter, but we 
> can't re-use directly it as it's important that clients know what the 
> exported handle could be used for.
> 
> Extending xdg-foreign would be a viable solution, but the lifespan of 
> handles needs to be different..
> 
> Honouring the activation request is entirely up to the compositor 
> which can have whatever advanced focus rules it wants.
> 

This is a topic close to my heart - I've been wanting to make GNOME 
Shell's naive “new surfaces always get focus” behaviour annoy me 
less!

How this works in Mir is that each input event that might signify user 
intent - button press/release, key press/release, touch down/up - 
includes a handle derived from the input timestamp. A couple of APIs - 
including the “raise window” API - then require the presentation of 
a handle. Just like your handle here, the Mir handle is a blob of bytes 
that can be shared via whatever out-of-band signalling mechanism is 
available.

I think I could pretty easily implement this proposal in a way that 
provides the same behaviour as Mir's API (and could easily be 
implemented on top of it), so there's evidence that this is 
implementable and usable ☺. Hm. If you wanted to, you could make this 
explicit by requiring an event serial in the export_surface request 
rather than the wl_surface.

I wonder if this shouldn't end up as a part of a new xdg_shell 
revision? It's already tied to xdg_shell in the activate_toplevel 
request, and I believe that this sort of focus information is a core 
part of desktop shell behaviour.

> Draft proposal below:
> 
> -----------
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <protocol name="xdg_foreign_activator">
> 
>   <copyright>
> 
>   </copyright>
> 
>   <description summary="Protocol for sharing focus between 
> cross-process xdg surfaces">
>       This protocol allows a top level to give up focus and pass it 
> to a specific other client.
> 
>       An example use case would be a chat client opening a link in a 
> browser, that should raise an existing window
>       or start the newly opened window with focus.
> 
>       The application releasing focus (focus_exported) fetches a 
> handle from the compositor and then passes it to another client using 
> a third party mechanism.
> 
>       The receiving application can use this handle to request focus 
> from the compositor.
>   </description>
> 
>   <interface name="zxdg_focus_exporter_v1" version="1">
>     <description summary="interface for exporting surfaces">
>       A global interface used for exporting surfaces that can later 
> be imported
>       using xdg_importer.
>     </description>
> 
>     <request name="destroy" type="destructor">
>       <description summary="destroy the xdg_focus_exporter object">
>         Notify the compositor that the xdg_exporter object will no 
> longer be
>         used.
>       </description>
>     </request>
> 
>     <request name="export_surface">
>       <description summary="export a toplevel surface">
>           It is an error to export a focus that is not mapped.
>       </description>
>       <arg name="id" type="new_id" interface="zxdg_focus_exported_v1"
>            summary="the new xdg_exported object"/>
>       <arg name="surface" type="object" interface="wl_surface"
>            summary="the surface to export"/>
>     </request>
>   </interface>
> 
>   <interface name="zxdg_focus_exported_v1" version="1">
>     <description summary="an exported activation handle">
>     </description>

Does this interface need to exist? Its purpose appears to be the 
return-value of export_surface, but that could just as easily be done 
as an event on zxdg_focus_exporter_v1?

As far as I can tell there's no resource management enabled by having 
this client-side object - the handle's lifetime is independent of the 
lifetime of this object, and there's no other resource tied to this 
object's lifetime.

> 
>     <request name="destroy" type="destructor">
>       <description summary="unexport the exported surface">
>           Inform the compositor that this focus_exported object is no 
> longer used.
>           The handle remains valid and can still be used by the 
> compositor. This is to allow windows to close themselves
>           after activating another application.
>       </description>
>     </request>
> 
>     <event name="handle">
>       <description summary="the exported activation handle">
>         The handle event contains the unique handle of this exported 
> surface
>         reference. It may be shared with any client, which then can 
> use it to
>         import the surface by calling 
> zxdg_activator_v1.activate_toplevel. A handle
>         may be used only once.
>       </description>
>       <arg name="handle" type="string" summary="the exported 
> activation handle"/>
>     </event>
>   </interface>
> 
>   <interface name="zxdg_focus_activator_v1" version="1">
>     <description summary="interface for importing surfaces">
>       A global interface used for importing surfaces exported by 
> xdg_focus_exporter.
>       With this interface, a client can create a reference to a 
> surface of
>       another client.
>     </description>

Your copy/paste is a little bit too zealous :).

> 
>     <request name="destroy" type="destructor">
>       <description summary="destroy the xdg_activator object">
>         Notify the compositor that the xdg_activator object will no 
> longer be
>         used.
>       </description>
>     </request>
> 
>     <request name="activate_toplevel">
>       <description summary="activate a toplevel surface">
>           Request to the compositor that this surface should claim 
> focus from the exported handle.
> 
>           This request can be sent at any time to raise an alread 
> mapped window or before the window is
>           mapped to request focus when the window is first configured.
> 
>           At this point the handle is invalidated and cannot be used 
> again.
> 
>           The compositor is free to ignore this request.
>       </description>
>       <arg name="toplevel" type="xdg_toplevel">
>       <arg name="handle" type="string"
>            summary="the exported activation handle"/>
>     </request>
>   </interface>
> 
> </protocol>
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180706/c345e1c3/attachment-0001.html>


More information about the wayland-devel mailing list