Warning
This project is a work in progress.
Winston-WM is a Wayland compositor built on Mir, designed for embedded systems where the full application stack is known at deploy time.
Winston-WM is not a general-purpose desktop window manager. It is purpose-built for embedded environments where:
- All applications are custom-made and trusted
- The developer decides exactly where each window appears and how large it is
- Layout is static and defined entirely in a TOML configuration file
- There is no need for dynamic tiling, window decorations, or user-driven window management
This makes Winston-WM a lightweight, predictable foundation for kiosk-style or appliance-style systems. The intended deployment path is a Yocto recipe that installs Winston as a drop-in replacement for Weston.
- IPC API — apps communicate with the WM at runtime to update window placement
- Background API — a dedicated background app queries Winston for color/image to render
| Distro | Command |
|---|---|
| Fedora | sudo dnf install gcc-c++ cmake mir-devel |
| Ubuntu | sudo apt install g++ cmake libmiral-dev |
cmake -B build
cmake --build buildThe binary is output to build/winston.
WAYLAND_DISPLAY controls both the socket name Winston creates and what clients use to connect to it. Pick any unused socket name:
WAYLAND_DISPLAY=wayland-99 ./build/winstonLaunch apps under Winston with the same display:
WAYLAND_DISPLAY=wayland-99 geditTo control the virtual output resolution when running nested inside another compositor:
MIR_SERVER_VIRTUAL_OUTPUT=1280x720 WAYLAND_DISPLAY=wayland-99 ./build/winstonWinston looks for its configuration at /etc/winston/winston.toml by default. Override with the WINSTON_CONFIG environment variable:
WINSTON_CONFIG=/path/to/my.toml WAYLAND_DISPLAY=wayland-99 ./build/winston[system]
desktops = 2 # number of virtual desktops (default: 1)
swipe_direction = "horizontal" # "horizontal" (left/right) or "vertical" (up/down)
background_color = "#1e1e1e"
# background_image = "/etc/winston/background.png"
[[application]]
name = "Calculator" # window title as reported to the WM — see note below
placement = [0, 0] # x, y from top-left corner
size = [150, 300] # width, height in pixels
z_level = 2 # 0=background 1=below 2=application (default) 3=always_on_top 4=above 5=overlay
desktops = [0, 1] # which desktops this window appears on (omit to show on all)| Value | Layer | Use case |
|---|---|---|
| 0 | background |
Desktop wallpaper |
| 1 | below |
Panels below normal windows |
| 2 | application |
Normal application windows (default) |
| 3 | always_on_top |
Persistent overlays |
| 4 | above |
Notifications, panels above windows |
| 5 | overlay |
Lock screens, top-most UI |
Set desktops in the [system] section to enable multiple virtual desktops. Swipe with a pointer or touch gesture to switch between them.
swipe_direction controls the gesture axis — use "horizontal" for left/right swiping (default) or "vertical" for up/down, matching the physical orientation of the display.
Each [[application]] entry can specify which desktops it appears on via the desktops array. Windows not listed for the current desktop are hidden. If desktops is omitted, the window appears on all desktops.
Winston stores color and image from the config and exposes them via its IPC API. A dedicated background application is responsible for querying these values at startup and rendering accordingly. Winston itself does not render the background.
The name field must match the window title the app reports to the compositor, which is often different from its executable name. Winston logs the reported name for every new window at startup:
[info] Placing new window Calculator
Check this output if a window is not being placed as expected.