Wayland debugging with Qtwayland, gstreamer waylandsink, wayland-lib and Weston

Terry Barnaby terry1 at beam.ltd.uk
Sun Feb 25 08:04:30 UTC 2024


I have investigated a bit further. I have built my own Weston server to 
run under X11 on Fedora37 so I can add printf's and debug more easily 
than using a cross compiled iMX8mp target system etc. I added a new 
dsmc-shell to Weston which is identical to kiosk-shell (apart from 
names) so I could play with that.

When It run my simple QWidget test program (test016-qt6-video-example) 
which creates one top level QWidget with a child QWidget to display the 
Gstreamer video in it, I see the following surfaces/subsurfaces when 
desktop_surface_committed() is called in the dsmc-shell.

Surface: 16 1044,620 mapped: 1 opaque: 0
  View: 0x29182b0
  Surface: 18 0,0 mapped: 0 opaque: 0
   Surface: 44 640,480 mapped: 1 opaque: 0
   Surface: 18 0,0 mapped: 0 opaque: 0
  Surface: 17 0,0 mapped: 0 opaque: 0
  Surface: 16 1044,620 mapped: 1 opaque: 0

Surface 16 is used by the top level QWidget, surface 18 is used by the 
Video QWidget and surface 44 is the GStreamer video display surface (I 
think!). This list is generated traversing the weston_surface's views 
and subsurface_list lists. The mapped is the "is_mapped" field of the 
Only the top level weston_surface has a weston_view in the views list it 
that is any relevance. "weston-debug scene-graph" only shows the tope 
most surface, no subsurfaces.

As mentioned before, If I use QPainter to draw into the video QWidget it 
actually draws into the top QWidgets 16 surface using Wayland protocol. 
I would have thought it would draw into its own QWidget surface 18 as it 
has Qt::WA_NativeWindow set ?

I assume that Qtwayland is not "activating" the video QWidget's surface 
or using it for some reason (send subsurface expose events ?) ?

I note in the qtwayland change logs, for the earlier QT5 for subsurface 
dist/changes-5.6.3: - [QTBUG-52118] Fixed subsurface positions sometimes 
not being committed.
dist/changes-5.11.2: - [QTBUG-69643] Fixed a bug where subsurfaces would 
not be rendered if clients added them before a WaylandQuickItem was 
created for the parent surface
dist/changes-5.12.0: - [QTBUG-49809] Added support for 
wl_subsurface.place_above and place_below in WaylandQuickItem.
dist/changes-5.15.2: - [QTBUG-86176] We now send subsurface expose 
events when a different toplevel (such as a dialog) is configured.

Could any of these be related ?

On 23/02/2024 09:29, Terry Barnaby wrote:
> Hi David,
> Many thanks for the reply and the info on how to get the ID.
> I have added a basic example with some debug output at: 
> https://portal.beam.ltd.uk/public//test016-qt6-video-example.tar.gz
> If there are any ideas of things I could look at/investigate I am all 
> ears!
> In a previous email I stated:
>> I have tried using "weston-debug scene-graph" and I am coming to the 
>> conclusion that qtwayland 6.5.0 is not really using native Wayland 
>> surfaces when Qt::WA_NativeWindow is used. From what I can see (and I 
>> could easily be wrong) the Wayland protocol shows wl_surfaces being 
>> created and two QWidget's QPlatformNativeInterface 
>> nativeResourceForWindow("surface", windowHandle()) function does 
>> return different wl_surface pointers but even at the QWidget level 
>> (ignoring gstreamer), a QPainter paint into each of these QWidgets 
>> actually uses Wayland to draw into just the one top level surface and 
>> "weston-debug scene-graph" shows only one application xdg_toplevel 
>> surface and no subsurfaces. I don't know how to determine the Wayland 
>> surface ID from a wl_surface pointer unfortunately to really check this.
>> If my Video QWidget(0) is a top level QWidget, then video is shown 
>> and "weston-debug scene-graph" shows the application xdg_toplevel and 
>> two wl_subsurfaces as children.
>> Unfortunately I think "weston-debug scene-graph" only shows surfaces 
>> that are actually "active" so I can't see all of the surfaces that 
>> Weston actually knows about (is there a method of doing this ?).
>> My feeling is that although Qtwayland is creating native surfaces, it 
>> actually only uses the one top level one and presumably doesn't 
>> "activate" (set a role, do something ?) with the other surfaces.
>> Does anyone know a good list/place where I can ask such detailed 
>> qtwayland questions ?
>> I guess I can work around this by manually creating a Wayland 
>> subsurface from the Qt top level surface and handing that to 
>> waylandsink and then manage this subsurface, like hiding, showing and 
>> resizing, when the QWidget is hidden/shown/resized.
>> Or could there be a way of "activating" the child QWidget's Wayland 
>> surface ? 
> Terry
> On 23/02/2024 08:35, David Edmundson wrote:
>> On Fri, Feb 23, 2024 at 6:15 AM Terry Barnaby <terry1 at beam.ltd.uk> 
>> wrote:
>>> I don't know how to determine the Wayland surface ID from a
>>> wl_surface pointer unfortunately to really check this.
>> wl_proxy_get_id(static_cast<wl_proxy*>(myWlSurface));
>>>>> Possibly when QWidget is below in hierarcy to be a child of of a 
>>>>> parent,
>>>>> as described in
>> That's fine.
>> A QWidget with WA_NativeWindow will create a QWindow with a parent. A
>> QWindow with a parent will create a subsurface in wayland terms.
>> But it is a subsurface where Qt is managing it and you're also
>> committing on it, which can be a bit confusing and going through
>> widgets to create a subsurface isn't really needed.
>> There's a bunch of other options there.
>> ---
>> Can you link your test app. You can send me a private email and I'll
>> take a look.  It doesn't seem like a core wayland problem more a
>> Qt/application setup issue so far. Then we can follow it up on Qt's
>> Jira if there is a Qt issue.
>> David Edmundson  - QtWayland Maintainer

More information about the wayland-devel mailing list