Screenshot through x11 on Xwayland

Zdeněk Žamberský zzambers at redhat.com
Mon Oct 18 21:49:54 UTC 2021


Hi,

I experimented a bit with X11 approach. I made simple program [1], which 
obtains
pixel data for each top-level X11 window, combines them to single buffer 
and then
saves it to png file. It has some limitations, most notably not being 
able to
capture native wayland windows and loss of transparency information.
However, I think, it is still interesting.

I created 2 screenshots from gnome-shell on wayland (RHEL-8), first one 
[2] is screenshot
as produced by this program, second one [3] shows what was actually 
visible on VMs display.

I have not yet tested it on Xwayland with other graphical environments 
than gnome-shell.
(But feel free to experiment with this program on your wayland desktop.)


Some technical notes (from testing on gnome-shell):
- Xwayland is xserver, which runs as wayland client in "rootless" mode 
(see [4]),
   in which root window has no pixel storage, but otherwise it still exists.
   (not to be confused with running xserver as non-root user, which is 
sometimes also referred as rootless mode)
- XGetImage for both root window and "Composite Overlay Window" (defined 
in composite extension [5]) fail with BadMatch
- XQueryTree [6] can be used on root window to obtain list of it's 
children (x11 windows) in stacking order (bottom to top)
- Image of individual top-level windows (children of the root window) 
can be obtained by XGetImage [7],
   but window has to meet following conditions (otherwise it fails with 
BadMatch):
   - class is InputOutput (not InputOnly)
   - map_state is IsViewable
   - area specified does not lies fully inside of the root window
- pixel data obtained by XGetImage do not contain alpha information 
(btw. xserver (Xwayland) reports 24bit depth),
   so transparent pixels became opaque (see window shadows by gnome 
shell and shaped window (xeyes) on linked screenshots)
- nor pixel data nor any other information about native wayland windows 
can be obtained through x11 (Xwayland),
   so they are completely missing on the screenshot (also areas of x11 
windows covered by them become visible)


This approach is far from perfect, but perhaps could be used as last resort
to support some sort of screenshot on Xwayland in graphical environment 
agnostic way (needs to be tested).
(Probably still better than array of black pixels after XGetImage on 
root window fails...)


[1] https://github.com/zzambers/wayland-experiments/tree/main/x11-screenshot
[2] 
https://github.com/zzambers/wayland-experiments/blob/fff27096e89bcb76ee43329ce987ccbb66dc4099/Screenshot-gnome-x11.png
[3] 
https://github.com/zzambers/wayland-experiments/blob/fff27096e89bcb76ee43329ce987ccbb66dc4099/Screenshot-gnome-vm.png
[4] 
https://gitlab.freedesktop.org/xorg/xserver/-/blob/ca1dfdc9aa4b548de624d3a9af5147a998ba3d79/miext/rootless/README.txt
[5] https://www.x.org/releases/X11R7.5/doc/compositeproto/compositeproto.txt
[6] 
https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#XQueryTree
[7] 
https://www.x.org/releases/current/doc/libX11/libX11/libX11.html#XGetImage

-- 
Zdeněk Žamberský
OpenJDK QE
Red Hat



More information about the wakefield-dev mailing list