← Otto Developer GuideWayland protocols
What each protocol means to a user is in Open standards. The freedesktop/XDG file and D-Bus standards around them are in XDG specifications. This page owns every protocol, the
xdg_*ones included.
Otto follows Smithay’s “one big compositor state” architecture: nearly all
protocol state and every handler hangs off a single struct, Otto<BackendData>.
Learning where that struct is built, and how Smithay routes requests into it,
makes the rest of the codebase navigable.
Supported protocols
Versions are the ones the global advertises. Otto’s Smithay is the nongio fork
pinned in Cargo.toml. Which globals are restricted, and to whom, is under
Availability.
Core and shells
| Global | v | Implementation |
|---|---|---|
wl_compositor, wl_subcompositor | 5, 1 | CompositorHandler in src/shell/mod.rs |
wl_shm | 2 | src/state/mod.rs |
wl_seat | 9 | src/state/seat_handler.rs |
wl_data_device_manager | 3 | src/state/data_device_handler.rs, dnd_grab_handler.rs |
wl_output | 4 | src/udev/device.rs, src/winit.rs, src/x11.rs, src/screenshare/mod.rs |
zxdg_output_manager_v1 | 3 | OutputManagerState::new_with_xdg_output |
xdg_wm_base | 7 | XdgShellHandler in src/shell/xdg.rs |
zxdg_decoration_manager_v1, org_kde_kwin_server_decoration_manager | 1, 1 | src/state/xdg_decoration_handler.rs |
xdg_wm_dialog_v1 | 1 | XdgDialogHandler in src/state/mod.rs, read in src/shell/tiling.rs |
xdg_activation_v1 | 1 | src/state/xdg_activation_handler.rs |
zxdg_exporter_v2, zxdg_importer_v2 | 1 | XdgForeignHandler in src/state/mod.rs |
zwlr_layer_shell_v1 | 5 | src/shell/layer.rs, src/shell/mod.rs |
xwayland_shell_v1, zwp_xwayland_keyboard_grab_manager_v1 | 1, 1 | src/state/xwayland_handler.rs, src/shell/x11.rs |
ext_background_effect_manager_v1 | 1 | src/background_effect.rs, see specs/background-effect.md |
org_kde_kwin_appmenu_manager | 2 | src/state/kde_appmenu.rs |
Buffers, timing and scaling
| Global | v | Implementation |
|---|---|---|
zwp_linux_dmabuf_v1 | 6 | DmabufHandler in src/udev/, src/winit.rs, src/x11.rs |
wl_drm | — | src/udev/init.rs, src/winit.rs, src/x11.rs |
wp_linux_drm_syncobj_manager_v1 | 1 | src/udev/init.rs, src/udev/mod.rs |
wp_drm_lease_device_v1 | 1 | src/udev/device.rs, src/udev/mod.rs |
wp_presentation | 2 | post_repaint / take_presentation_feedback, src/udev/render.rs |
wp_fractional_scale_manager_v1 | 1 | src/state/fractional_scale_handler.rs |
wp_viewporter | 1 | src/state/mod.rs |
wp_cursor_shape_manager_v1 | 2 | src/state/mod.rs |
Input
| Global | v | Implementation |
|---|---|---|
zwp_relative_pointer_manager_v1 | 1 | src/input/pointer.rs |
zwp_pointer_gestures_v1 | 3 | src/input/gestures.rs |
zwp_pointer_constraints_v1 | 1 | src/state/input_method_handler.rs, src/input/pointer.rs |
zwp_tablet_manager_v2 | 1 | src/input/tablet.rs |
zwp_keyboard_shortcuts_inhibit_manager_v1 | 1 | src/state/mod.rs, survives_shortcut_inhibition in src/input/keyboard.rs |
zwp_text_input_manager_v3 | 1 | src/state/mod.rs |
zwp_input_method_manager_v2 | 1 | src/state/input_method_handler.rs |
zwp_virtual_keyboard_manager_v1 | 1 | src/state/mod.rs |
zwlr_virtual_pointer_manager_v1 | 2 | src/state/virtual_pointer.rs |
Selection
| Global | v | Implementation |
|---|---|---|
zwp_primary_selection_device_manager_v1 | 1 | src/state/selection_handler.rs |
zwlr_data_control_manager_v1, ext_data_control_manager_v1 | 2, 1 | src/state/data_device_handler.rs |
Session, windows, capture
| Global | v | Implementation |
|---|---|---|
ext_session_lock_manager_v1 | 1 | src/state/session_lock_handler.rs, src/lock.rs |
zwp_idle_inhibit_manager_v1 | 1 | src/state/mod.rs, checked in src/lock.rs |
wp_security_context_manager_v1 | 1 | src/state/security_context_handler.rs, src/sandbox.rs |
ext_foreign_toplevel_list_v1 | 1 | src/state/foreign_toplevel_list_handler.rs |
zwlr_foreign_toplevel_manager_v1 | 3 | src/state/wlr_foreign_toplevel.rs, see foreign-toplevel.md |
zwlr_screencopy_manager_v1 | 3 | src/state/screencopy.rs |
zwlr_gamma_control_manager_v1 | 1 | src/state/gamma_control.rs, src/udev/gamma.rs |
Otto’s own
| Global | v | Implementation |
|---|---|---|
otto_surface_style_manager_v1 | 5 | src/surface_style/, see surface-style-protocol.md |
otto_dock_manager_v1 | 1 | src/otto_dock/ |
otto_canvas_manager_v1 | 5 | src/otto_canvas/ |
otto_text_cursor_manager_v1 | 1 | src/text_cursor/; unavailable is a normal answer |
Availability
Every global above is offered to every client on every backend, except:
- Hidden from sandboxed clients (tagged through
wp_security_context_v1,src/sandbox.rs): layer shell, keyboard shortcuts inhibit, input method, virtual keyboard and pointer, both data controls, both foreign toplevel lists, screencopy and gamma control. - Only Otto’s own locker:
ext_session_lock_manager_v1(ClientState::is_otto_locker), soswaylockand the like cannot lock. - udev only: relative pointer (
HAS_RELATIVE_MOTION), pointer gestures (HAS_GESTURES), DRM syncobj (when the GPU supports syncobj eventfd) and DRM lease (one per node).wp_presentationis everywhere but sends feedback on udev only; tablet events come from libinput, so udev too; gamma control fails without DRM. - Per backend:
zwp_linux_dmabuf_v1(v6, v3 without feedback and always v3 headless),wl_drmandwl_output. xwaylandfeature (on by default):xwayland_shell_v1and the Xwayland keyboard grab.
Behaviour worth knowing: wl_shm offers only the mandatory ARGB8888 and
XRGB8888; xdg-activation tokens need a fresh input serial and expire after
10 s; the xdg-dialog modal hint floats a parentless window when tiling;
background effect blurs the whole surface, whatever the region; keyboard
shortcuts inhibit grants every request, but lock and VT switch still fire;
wlr foreign toplevel ignores set_rectangle and the fullscreen output;
screencopy treats copy_with_damage as a plain copy.
Not served
wp_single_pixel_buffer, wp_alpha_modifier, wp_commit_timing, wp_fifo,
wp_content_type, wp_tearing_control, wp_color_management,
wp_pointer_warp, wl_fixes, xdg_system_bell, xdg_toplevel_icon,
xdg_toplevel_tag, xdg_toplevel_drag, ext_idle_notify,
ext_image_copy_capture / ext_image_capture_source, ext_workspace,
wlr_output_management, wlr_output_power_management. Most exist in the
Smithay fork and need only wiring.
The big state: Otto<BackendData>
Otto<BackendData> lives in src/state/mod.rs and holds:
- High-level compositor state: workspaces, popups, input state, the scene graph
- Smithay protocol state objects:
CompositorState,XdgShellState,WlrLayerShellState,PresentationState,ShmState, … - Backend-specific data (
BackendData) for rendering and outputs
So self.xdg_shell_state or self.shm_state is one of those Smithay objects
stored directly inside Otto. There is no separate protocol layer to look for.
Where it is initialized
Most globals are created in Otto::init(...) in src/state/mod.rs:
- The Wayland socket and client dispatch source are installed into calloop.
- Smithay protocol states are constructed (
CompositorState::new,XdgShellState::new,PresentationState::new, …). - Capability-gated globals are created conditionally, based on what the backend
can actually do (
Backend::HAS_GESTURES,HAS_RELATIVE_MOTION). - Globals a sandboxed client may not see are created with a filter
(
new_with_filter, or theUnsandboxedOnlywrapper around aGlobalDispatch2). The hand-rolled globals checksandbox::is_sandboxed_clientin their owncan_view.
Backends create their own globals in their entrypoints: zwp_linux_dmabuf_v1,
wl_drm, wl_output, and on udev syncobj and DRM lease.
How dispatch works
Otto’s Smithay fork routes requests through Smithay’s GlobalDispatch2 /
Dispatch2 traits rather than per-protocol delegate_*! macros. The pattern:
- Otto stores the protocol state object (
xdg_shell_state: XdgShellState). - Otto implements the matching handler trait
(
impl XdgShellHandler for Otto<BackendData>). - One
smithay::delegate_dispatch2!insrc/state/mod.rsgenerates the dispatch glue for every Smithay protocol at once.
Globals Smithay does not ship (virtual pointer, screencopy, gamma, foreign
toplevel management, background effect, Otto’s own) are dispatched with
wayland_server::delegate_dispatch! / delegate_global_dispatch! next to
that line, pointing at their state type.
Finding a protocol
- Find the state: grep
src/state/mod.rsfor the protocol’s…State::new(or the global’s interface name for hand-rolled ones). - Find the handler impl:
impl<BackendData: Backend> XdgShellHandler for Otto<BackendData>. - Backend-specific globals live in
src/udev/,src/winit.rs,src/x11.rs.
Handlers are split roughly like this:
src/state/*.rs: core protocol handlers (seat, selection, input method, fractional scale, foreign toplevel, session lock, screencopy, gamma, …)src/shell/*.rs: xdg-shell, layer-shell, XWayland, and surface commit plumbingsrc/{udev,winit,x11}.rs: backend-specific globals and handler impls
Protocols with XML in the tree
Otto ships the XML for the protocols nothing else generates bindings for. It
lives in protocols/; the compositor and otto-kit
(components/otto-kit/src/protocols/) both generate from it.
| Protocol | Implementation | What it does |
|---|---|---|
otto-surface-style-unstable-v1 | src/surface_style/ | Lets a client style and animate its own surface through the compositor’s scene graph: corner radius, shadow, opacity, transforms, batched in transactions. See surface-style-protocol.md. |
otto-dock-v1 | src/otto_dock/ | Lets a client contribute items to the compositor-drawn dock |
otto-canvas-v1 | src/otto_canvas/ | Items on the side canvas |
otto-text-cursor-v1 | src/text_cursor/ | Tells a client where the desktop’s text cursor is, so a picker or completion popup can sit beside it |
wlr-gamma-control-unstable-v1 | src/state/gamma_control.rs | Gamma ramps, for colour temperature tools |
| KDE appmenu | src/state/kde_appmenu.rs | Where a Qt/KDE app’s menu lives on the bus, for the top bar’s global menu |
The first four are Otto’s own. Two files are not used:
protocols/sc-layer-v1.xml is not implemented (some identifiers still say
sc_layer), and wlr-foreign-toplevel-management-unstable-v1.xml is kept
for reference while the code uses the wayland_protocols_wlr crate.
What Otto’s apps use
otto-kit is the client side: core, xdg_wm_base, xdg-decoration,
xdg-activation, xdg-foreign, xdg-dialog, xdg-output, fractional scale,
viewporter, cursor shape, text-input-v3, pointer gestures, keyboard shortcuts
inhibit, background effect, KDE appmenu and Otto’s own protocols. Beyond it:
layer shell (bar, islands, desk, launcher, lock, greeter, emoji, dictate,
authorize), session lock (otto-lock), wlr foreign toplevel (launcher, focus
watcher), wlr virtual pointer (kinetic scrolling, otto-rdp), virtual
keyboard (otto-emoji, otto-rdp), input-method-v2 (otto-dictate,
otto-stash) and wlr data control (otto-stash).