Table of Contents
Wayland Backend
The system cl-windowing/wayland is the Wayland backend, registered as
:wayland. It talks to the compositor through libwayland-client, by way
of cl-wl, compiles keymaps with
libxkbcommon, by way of cl-xkbcommon,
and draws cursor themes with libwayland-cursor where the compositor draws
no cursors by name. Everywhere but on Windows, it is the backend
open-window-system uses without :backend.
Its package, cl-windowing/wayland, exports the classes
wayland-window-system, wayland-window, and its subclasses
wayland-toplevel and wayland-popup. Programs do not need them:
everything goes through cl-windowing.
Options
open-window-system passes these to the backend:
| Option | Meaning |
|---|---|
:display-name |
The compositor's socket, such as "wayland-1". By default $WAYLAND_DISPLAY. |
:connection |
A cl-wl:display connected already. The window system uses it, and flushes it but does not disconnect it when it closes. |
With :connection, process-events dispatches every event of that
display, those of objects you made yourself included. cl-windowing's own
tests use it to run against cl-wl's in-process compositor.
Protocols
| Global | Version | Needed | What for |
|---|---|---|---|
wl_compositor |
up to 6 | Yes | Surfaces. From version 6, the preferred buffer scale. |
xdg_wm_base |
up to 6 | Yes | Top-level windows and popups. cl-windowing answers its pings. From version 3, popups can be placed again with reposition-popup. |
zxdg_decoration_manager_v1 |
1 | No | Server-side decorations. |
wp_viewporter |
1 | No | With fractional scales: showing a frame at the window's size. |
wp_fractional_scale_manager_v1 |
1 | No | Fractional scales. Used only together with wp_viewporter. |
wl_seat |
up to 9 | No | Keyboard and pointer, from the first seat. cl-windowing repeats keys itself, so version 10 is not needed. |
wl_output |
up to 4 | No | Output scales, for compositors without the preferred buffer scale. Followed as outputs are plugged in and out. |
wp_cursor_shape_manager_v1 |
1 | No | Cursors the compositor draws by name. |
wl_shm |
1 | No | Cursor images from the user's theme, where the compositor offers no cursor shapes. |
zwp_text_input_manager_v3 |
1 | No | Input methods, through text-input-v3. |
wl_data_device_manager |
up to 3 | No | The clipboard. :clipboard is in window-system-capabilities with it. |
zwp_pointer_constraints_v1, zwp_relative_pointer_manager_v1 |
1 | No | Confining and capturing the pointer, and the captured pointer's motion. :pointer-capture is in window-system-capabilities with both. |
xdg_wm_dialog_v1 |
1 | No | Marking dialogs as dialogs, modal or not. |
Without a needed global, open-window-system signals
window-system-error naming it.
Windows
A window is an xdg_toplevel on a wl_surface, a wayland-toplevel.
create-windowsets the title and the app ID, asks for server-side decorations where offered, and commits the surface without a buffer, which asks the compositor for the first configure.- The
xdg_toplevel.configureandxdg_surface.configureevents are a size proposal. A width or height of 0 leaves that dimension to the window. The serial is acknowledged withxdg_surface.ack_configureat once for a first or unchanged size, otherwise inadopt-window-size. See Resizing and Scaling. xdg_toplevel.closebecomes a:closeevent.- The states a configure carries decide who sizes the window. While it is
maximised, fullscreen or tiled, or the user is resizing it, the
compositor does, and
set-window-sizeasks nothing. Otherwise the window takes the sizeset-window-sizeasks for by drawing at it, as xdg-shell lets a window size itself, and a configure that comes before the compositor has seen a frame at that size, proposing the old one, does not undo it. window-fullscreen-pfollows thefullscreenstate of the configures: setting it sendsset_fullscreenorunset_fullscreen, and the compositor makes the window fullscreen on the output it chooses.
A popup is an xdg_popup on a wl_surface, a wayland-popup, placed by
the compositor as an xdg_positioner describes create-popup's placement.
A popup that grabs takes the grab with the serial of the latest key or
button press. xdg_popup.popup_done becomes a :close event, and
popup-dismissed-p becomes true. See Popups.
Dialogs
A dialog is a wayland-toplevel given its parent's toplevel with
xdg_toplevel.set_parent before its first commit, and, where the
compositor offers xdg_wm_dialog_v1, an xdg_dialog_v1 that marks it as
a dialog, with set_modal for a modal one. The xdg_dialog_v1 is
destroyed before the toplevel. xdg-shell honours set_parent only for a
parent that has been drawn: a dialog made on one that has not been is a
toplevel of its own to the compositor, though cl-windowing still counts
it the parent's dialog. The compositor places the dialog, and may show a
modal one specially, as attached to its parent; it may still deliver
input to the parent, which the core drops, as xdg-dialog asks of clients.
See Dialogs.
Scale
| Offered | Scale from | Told back with |
|---|---|---|
wp_fractional_scale_v1 and wp_viewporter |
preferred_scale, in 120ths |
wp_viewport.set_destination, to the window's size in units; unset at scale 1 |
wl_surface version 6 |
wl_surface.preferred_buffer_scale |
wl_surface.set_buffer_scale |
| Neither | The largest wl_output.scale of the outputs the surface has entered, or 1 |
wl_surface.set_buffer_scale |
The scale is told back to the compositor in adopt-window-size, just
before the frame drawn at it.
Input
- Input comes from the first
wl_seatthe compositor offers. Its keyboard and pointer are taken when the seat gains them and released when it loses them, andwindow-system-capabilitiesfollows. - Keymaps must be in the
xkb_v1format. The keymap is read from the file descriptor the compositor sends, compiled by libxkbcommon, and replaced whenever the compositor sends a new one. - Dead keys and compose sequences use the compose table of the locale
(
$LC_ALL,$LC_CTYPEor$LANG) and the user's~/.XCompose. - Keys are repeated by cl-windowing, at the rate and delay of
wl_keyboard.repeat_info, insideprocess-events. - Pointer events are gathered per
wl_pointer.frame, from version 5. Scroll steps come fromaxis_value120oraxis_discretefor wheels, and fromaxisdivided by 10 for continuous scrolling. - The cursor over a window is set after each
wl_pointer.enter. Withwp_cursor_shape_manager_v1, the compositor draws it from its name. Otherwise the backend draws it from the user's Xcursor theme, named by$XCURSOR_THEMEand$XCURSOR_SIZE, through libwayland-cursor, at the window's scale, on a surface of its own, and animates animated cursors. A cursor the theme lacks is shown as:default. - Input methods speak text-input-v3. The caret and the surrounding text are
sent when they change, and the input method's
preedit_string,commit_stringanddelete_surrounding_textbecome:preedit,:textand:delete-surroundingevents, in the order the protocol applies them. - The pointer is confined and captured through pointer-constraints-v1, with persistent constraints, and the captured pointer's motion comes from relative-pointer-v1's unaccelerated motion.
- The clipboard is the seat's
wl_data_device. Its text is read through a pipe from the program whose text it is, and offered from awl_data_sourcein the MIME typestext/plain;charset=utf-8,UTF8_STRINGandtext/plain. Setting it needs the serial of an input event, so it signalswindow-system-errorwhile no window of the program has the keyboard focus.
Compositors
What to expect on some compositors:
| Compositor | Decorations | Scales |
|---|---|---|
| KDE Plasma (KWin) | Server-side | Fractional |
| Sway and other wlroots compositors | Server-side | Fractional, in recent versions |
| GNOME (Mutter) | None: GNOME offers no server-side decorations | Fractional, in recent versions, when fractional scaling is enabled |
| Weston | None | Whole numbers, from the outputs; weston --scale=2 gives 2 |
On compositors without server-side decorations, windows have no title bar until the engine draws its own. They can still be moved and resized with the compositor's keyboard and pointer shortcuts.
A headless Weston, weston --backend=headless, is what the Vulkan tests
present to. It has no seat, so no keyboard, pointer or clipboard to set,
but it offers pointer constraints and relative pointers.
Locking
Everything the backend does on the connection happens holding the window
system's lock, except the wait for the compositor, cl-wl:read-events,
which cl-wl allows to run while another thread uses the display. See
Threads.