Wayland#

Wayland is the modern Linux display protocol. Unlike X11, there is no central server brokering between clients; the compositor is the server, and each client talks to it directly over a private Unix socket. Clients cannot read each other’s pixels, intercept each other’s keystrokes, or inject input without an explicit grant through a portal.

For the operator this is a different threat model. The on-host keylogger primitive that X11 provides for free does not work on Wayland; tooling like xdotool and scrot either fail or fall through to Xwayland (an X11 server running as a Wayland client, isolated from the rest of the session). Automation on Wayland goes through ydotool (uinput) or compositor-specific IPC (swaymsg, hyprctl).

Anatomy#

        flowchart LR
    K[Kernel<br/>evdev / KMS / DRM] --> C[Compositor<br/>= server]
    C --> A1[Client app 1]
    C --> A2[Client app 2]
    C --> XW[Xwayland<br/>X11 clients]
    C -. portal .- P[xdg-desktop-portal<br/>screencast, screenshot]
    

Piece

Role

Compositor

Owns the framebuffer, input, and per-client surfaces. Sway, Hyprland, KWin (KDE), Mutter (GNOME), River, Niri.

Wayland protocol

The wire format between client and compositor. Versioned through XML protocol files.

Xwayland

A full X server running as a Wayland client. Provides a sandbox for legacy X11 apps; they cannot see Wayland-native windows.

xdg-desktop-portal

The mediator for “permission-required” actions like screen capture, file picker, and global hotkeys.

Tools#

wayland-info#

Show compositor capabilities, advertised protocols, and outputs. The Wayland equivalent of xdpyinfo.

$ wayland-info | head -40

wlr-randr / kanshi#

Configure outputs on wlroots-based compositors (Sway, Hyprland, River). kanshi applies per-profile output configs on hot-plug.

$ wlr-randr                                    # list outputs
$ wlr-randr --output HDMI-A-1 --on --pos 1920,0

ydotool#

Synthetic input via the kernel uinput device. Requires root or membership in the input group; works in any session because it operates below Wayland.

$ sudo ydotoold &                              # daemon
$ ydotool type "hello"
$ ydotool key 29:1 56:1 31:1 31:0 56:0 29:0    # Ctrl+Alt+s

grim + slurp#

Screen capture on wlroots compositors. grim takes the shot, slurp selects a region. The compositor decides whether to honour the request.

$ grim screen.png
$ grim -g "$(slurp)" region.png

wf-recorder#

Screen recording for wlroots. GNOME and KDE use compositor-native recorders through the portal.

$ wf-recorder -f recording.mp4

swaymsg / hyprctl#

Compositor IPC. Query workspaces, focus windows, change layout, bind keys at runtime.

$ swaymsg -t get_tree | jq '.. | .name? // empty'
$ hyprctl clients

Constraints#

  • No global keylogger. A Wayland client cannot read keystrokes destined for a different surface.

  • No window-to-window pixel reads. Screen capture goes through the portal and is compositor-mediated.

  • Xwayland is the bypass. Legacy X11 apps still have full X-style access to each other under Xwayland, just not to native Wayland clients. Audit the app mix.

  • Compositor maturity varies. Hyprland and Sway expose rich IPC; Mutter and KWin lock more of it behind D-Bus.

Files#

Runtime#

Path

Purpose

$XDG_RUNTIME_DIR/wayland-0

Compositor socket. Per-user, per-session, mode 0700.

$XDG_RUNTIME_DIR/wayland-0.lock

Lock file. Multiple compositors increment the number.

Configuration (per compositor)#

Path

Purpose

~/.config/sway/config

Sway compositor config.

~/.config/hypr/hyprland.conf

Hyprland compositor config.

Variables#

Session#

Variable

Purpose

WAYLAND_DISPLAY

Name of the compositor socket inside $XDG_RUNTIME_DIR; typically wayland-0.

XDG_SESSION_TYPE

wayland confirms the session; x11 means X11 applies instead.

XDG_RUNTIME_DIR

Where the compositor socket lives. /run/user/<uid> on systemd.

DISPLAY

Set only when Xwayland is running. Names the X server, not the Wayland one.

Common Tasks#

Confirm the session is Wayland and the compositor name.

$ echo "$XDG_SESSION_TYPE  $WAYLAND_DISPLAY"
$ loginctl show-session $(loginctl | awk '/'$USER'/{print $1}') -p Type

List the Wayland protocols this compositor exposes.

$ wayland-info | grep "interface:"

See if any X11 apps are running under Xwayland.

$ ps -ef | grep -i xwayland
$ xlsclients                                   # if Xwayland is up

References#