[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 

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 

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