Wayland & X11 Display Backends
Relevant source files
The following files were used as context for generating this wiki page:
Kaleidux utilizes a dual-backend architecture to support both modern Wayland compositors and legacy X11 display servers. These backends are responsible for discovering connected outputs, managing wallpaper surfaces (or windows), and providing the low-level handles required by the WGPU rendering pipeline. The system detects the environment at runtime by checking the WAYLAND_DISPLAY and DISPLAY environment variables to select the appropriate loop.
The display backends act as the bridge between the desktop environment and the internal Renderer, ensuring that wallpapers are correctly positioned, layered, and synchronized with the compositor's refresh rate.
Sources: kaleidux-daemon/src/main.rs:279-289, kaleidux-daemon/src/wayland.rs:1-15, kaleidux-daemon/src/x11.rs:1-15
Backend Detection and Initialization
The daemon identifies the active display protocol during startup. If WAYLAND_DISPLAY is missing but DISPLAY is present, it defaults to the X11 backend. Otherwise, it attempts to initialize the Wayland backend. Each backend implements a specific event loop that manages its unique lifecycle requirements, such as Wayland's roundtrips or X11's event polling.
The diagram shows the decision logic for backend selection and the subsequent entry into protocol-specific loops.
Sources: kaleidux-daemon/src/main.rs:279-289
Wayland Backend Implementation
The Wayland backend is built using smithay-client-toolkit (SCTK) and implements the wlr-layer-shell protocol. This allows Kaleidux to request a "Background" layer for its surfaces, ensuring they stay behind all other windows and occupy the entire screen.
Layer Shell Management
The WaylandBackend struct manages the registry, compositor state, and layer shell bindings. Surfaces are created as LayerSurface objects, which are anchored to all edges of a wl_output.
| Component | Responsibility |
|---|---|
RegistryState | Tracks global objects like outputs and the layer shell. |
LayerShell | Binds the protocol for specialized desktop surfaces. |
LayerSurface | A specific wallpaper instance anchored to an output. |
pending_resizes | Queue for handling compositor-initiated window size changes. |
frame_callback_ready | Tracks surfaces ready for new frame submission. |
Sources: kaleidux-daemon/src/wayland.rs:88-100, kaleidux-daemon/src/wayland.rs:125-147
Rendering Synchronization (Frame Callbacks)
Wayland rendering is synchronized via the wl_surface.frame event. The backend only signals the Renderer to produce a new frame when the compositor acknowledges the previous one. This prevents frame accumulation and reduces CPU/GPU overhead.
The sequence diagram illustrates the reactive rendering cycle required by the Wayland protocol.
Sources: kaleidux-daemon/src/wayland.rs:194-219, kaleidux-daemon/src/renderer.rs:770-798
X11 Backend Implementation
The X11 backend uses the x11rb crate with XCB bindings. It discovers monitors through the RandR extension and creates specialized "Desktop" type windows for each display.
Window Stacking and Atoms
To ensure wallpapers behave correctly under various Window Managers (WMs), the backend inters several EWMH atoms. It specifically sets _NET_WM_WINDOW_TYPE_DESKTOP and applies states such as _NET_WM_STATE_BELOW and _NET_WM_STATE_STICKY to keep the window at the bottom of the stack and present on all workspaces.
Sources: kaleidux-daemon/src/x11.rs:36-64, kaleidux-daemon/src/x11.rs:170-205
RandR Output Discovery
The backend queries the current screen resources via RandR to map windows to physical monitors. It tracks "dirty" states for monitor configurations to re-query only when the display layout changes (e.g., plugging in a new monitor).
The flow shows the steps required to establish a wallpaper window on an X11 display.
Sources: kaleidux-daemon/src/x11.rs:107-148, kaleidux-daemon/src/x11.rs:214-222
Common Backend Logic
Regardless of the protocol, the main loop manages resource cleanup and configuration synchronization for all active renderers.
Renderer Management
- Orphan Cleanup: Renderers are retained only if their associated output still exists in the backend's state.
- Resize Handling: Backends push resize events into a queue, which the main loop processes by calling
Renderer::resize_checked. - Configuration: When the configuration reloads, the loop iterates through all active renderers to re-apply
OutputConfig.
Sources: kaleidux-daemon/src/main.rs:568-580, kaleidux-daemon/src/main.rs:885-896
Performance Metrics
The system tracks backend-specific performance through a centralized PerformanceMetrics module.
This diagram represents the structure used to track initialization and frame delivery times for both backends.
Sources: kaleidux-daemon/src/metrics.rs:10-40
Comparison of Backend Characteristics
| Feature | Wayland | X11 |
|---|---|---|
| Library | smithay-client-toolkit | x11rb / xcb |
| Layering | wlr-layer-shell (Background) | _NET_WM_WINDOW_TYPE_DESKTOP |
| Sync | Explicit Frame Callbacks | Flush-based / Redraw Events |
| Resizing | Configure Events (Serial-based) | ConfigureNotify / Expose |
| Handle Type | WaylandWindowHandle | XcbWindowHandle |
Sources: kaleidux-daemon/src/wayland.rs:43-70, kaleidux-daemon/src/x11.rs:226-248
Summary
The Kaleidux display backends provide a robust foundation for multi-monitor wallpaper rendering. By abstracting the complexities of Wayland's layer shell and X11's RandR/EWMH protocols, the system allows the Renderer to focus on hardware-accelerated GLSL transitions while maintaining consistent behavior across different Linux desktop environments. The architecture ensures that wallpapers are correctly layered, synchronized, and responsive to display configuration changes.