Implement Xwayland support
In order to support clients that do not use a toolkit that has a Wayland backend, we have to implement XWayland support. XWayland is a rootless X11 server that runs as a Wayland client. X11 clients connect to XWayland just as they'd connect to a regular Xorg instance, and XWayland (more or less) converts the X11 protocol requests into Wayland protocol requests.
XWayland support – perhaps surprisingly – requires the Wayland compositor to integrate a more-or-less fully-functional X11 window manager. Smithay has an xwayland module that handles a lot of the boring, boilerplate stuff, but there will be some work to be done to integrate that into our own window management logic.
Collecting some (so far non-exhaustive) specifics:
-
Window cycling include/not include skip-taskbar and skip-pager windows. (
cycle_minimum) -
Handle
_GTK_FRAME_EXTENTSin the window positioning code. This values is used for CSD windows so the client can tell the WM about things like drop shadows etc. Ideally Smithay should handle it (and return the full extents inSpaceElement::bbox(), like is the case for xdg-toplevels), and then we won't need to special-case it. -
Set
_NET_FRAME_EXTENTSon decorated X11 windows to tell them the extents of their decorations. -
Add support for
_NET_WM_STATE_STICKYto smithay. -
Add support for
_NET_WM_STATE_DEMANDS_ATTENTIONto smithay. (urgent_blink,repeat_urgent_blink) -
Add support for focus-stealing prevention (
prevent_focus_stealing). On X11, that's done with a combination of_NET_USER_TIME, with focus passing depending on comparing things between two windows like_NET_WM_PIDandWM_CLASS. These properties, however, are set by the client. On X11 they are trusted, because applications are assumed to be well behaved, but Wayland theoretically has a higher standard. Instead of trusting these values:- Instead of
_NET_WM_USER_TIME, I can track when the user has last interacted with a window via pointer button/axis events, touch events, or key events. - Instead of
_NET_WM_PID, I can check if they are the same by the X11 window ID. But I need to look atresource_id_maskfrom an X11 connection setup reply in order to tell what bits of the ID uniquely identify a client. (Note that I need to invert it;resource_id_mask & 0x1fffffffwill give me the mask I need, as X11 only ever uses 29 bits for its Window ID space.)
- Instead of
-
Support
WM_TAKE_FOCUS -
Support honoring or ignoring
WM_HINTS.focus+WM_TAKE_FOCUS(focus_hint) -
Set XSETTINGS on the X11 root window, and update it whenever any of our XSETTINGS-related xfconf properties change. The
Xwmstruct has aset_xsettings()method on it, so I don't even need to manually construct the window property. -
Set the
Xwmcursor when the cursor theme changes. - If the XWayland server crashes, try to restart it.
Edited by Brian Tarricone