Mapping surfaces created through a nested compositor to UI elements

Pekka Paalanen ppaalanen at gmail.com
Thu Jan 30 03:34:49 PST 2014


On Thu, 30 Jan 2014 10:32:03 +0100
Iago Toral <itoral at igalia.com> wrote:

> Hi,
> 
> in the process of porting webkitgtk+ to wayland and following advise
> provided here, I implemented a nested compositor to share surfaces
> between the two processes that do the rendering. This works fine with
> a single widget/surface, but things get a bit more complicated when
> dealing with various widgets (browser tabs, windows).
> 
> I am trying to understand if I can solve my problem, which is
> basically a problem of matching wayland surfaces created in the
> nested compositor with their corresponding widgets in the UI, within
> the scope of the wayland protocol or if I need to resort to ad-hoc
> communications between the two processes outside the protocol. Below
> I describe the problem in more detail together with the possible
> solutions I looked into and my conclusions. I'd appreciate a lot if
> someone could confirm whether these are correct:
> 
> As far as I understand the code in the nested client example from
> Weston, when there is need to repaint the UI it goes through all the
> surfaces in the compositor and paints them one by one. In our case,
> when GTK needs to repaint it will go through the widgets in the UI
> and ask them to repaint as needed. This means that we need to know,
> for a given widget, which is the surface in the nested compositor
> that provides the contents for it.
> 
> However, when the nested compositor receives a request to create a
> surface it will not know for which widget it is creating it (obviously
> information on things like UI widgets is outside the scope of the
> wayland protocol), and as far as I can see, there is no way for the
> client to provide this info to the compositor either when the surface
> is created or after it has been created.
> 
> Assuming that this is not something I can so using available APIs, I
> looked into adding this API to my nested compositor implementation,
> so I can have a surface constructor like this:
> 
> wl_compositor_create_surface_for_widget(struct wl_compositor*, int);
> 
> where that additional 'int' parameter would be used on the
> compositor's side to associate the new surface with a specific UI
> widget.
> 
> Unfortunately, for this I would really want to reuse existing code and
> APIs from wayland to do message communication between client and
> compositor, but a good part of this is private to wayland (the
> wl_closure stuff for example) so it feels like I would end up having
> to duplicate quite some code from Wayland in WebKit, which I think is
> really not a good idea. Also, the fact that these APIs have been kept
> internal to Wayland means that this is not something that developers
> are expected to do.
> 
> If the above is not a good solution either, I understand there would
> be no solution for my problem within the wayland protocol and I would
> need to add additional messages between the two processes outside the
> protocol after the surface is created in order to associate the
> surface and the widget on the compositor's side. In that case, I
> would need to communicate the widget ID and the ID of the Wayland
> object representing the surface (which I understand I'd get by
> calling wl_proxy_get_id on the client for the surface).
> 
> Is my analysis of the problem correct or is there some way in which I
> can achieve my objective within the wayland protocol?

Hi,

the short answer to your solution is "write a custom shell extension".

That means that you would be writing your own private Wayland protocol
extension in the same XML format as all Wayland protocol is already
defined. Let's take xdg_shell as an example:
http://cgit.freedesktop.org/wayland/weston/tree/protocol/xdg-shell.xml

A compositor advertises a global object of type xdg_shell. The
xdg_shell interface has two requests that allow you to add meaning to
wl_surfaces: get_xdg_surface and get_xdg_popup. These requests
associate additional information to the given wl_surface, and create a
new protocol object to allow manipulating the new features added to the
wl_surface object.

If all you need to do is to associate an integer ID to a wl_surface,
you could define a new global interface with a single request, that has
a wl_surface and the ID as arguments. If you need more, you can add
more like xdg_shell does. There are also many other examples of how
wl_surface can be extended with the help of a new global interface.

This new global interface would be advertised by the nested compositor
only, and the clients of that compositor would be using it. No-one else
would ever see it. The clients would use the standard wl_compositor to
create standard wl_surface objects, and then add new meaning to them
with your extension.

Does this help?

Btw. do not write an extension that has a new request to create
wl_surface objects, or any objects that are already creatable via other
interfaces. Doing so would lead to interface versioning problems, as
explained in:
http://wayland.freedesktop.org/docs/html/sect-Protocol-Versioning.html


Thanks,
pq


More information about the wayland-devel mailing list