WinNative can run a session on an embedded Wayland compositor instead of its X server. Wine’s
winewayland.drv connects to the compositor over a socket, the game’s Vulkan swapchain is shared
as dma-buf frames, and the compositor blits them to the screen through Turnip. The X server is
still created for input bookkeeping but never draws.
The compositor (app/src/main/cpp/waylandcomp) and the session design were written by
The412Banner for
Bannerlator and ported here; see
CREDITS.md.
displayBackend extra (x11 or wayland).Wayland can only be selected, and is only used at launch, when both hold:
lib/wine/aarch64-unix/winewayland.so and
lib/libvulkan_freedreno_wayland.so, the Wayland Turnip the game renders on.
WinNative writes its own Vulkan ICD manifests for the bundled Turnips as
share/vulkan/icd.d/wayland_turnip[_variant].json and points winewayland at the chosen one
through BANNER_WAYLAND_VK_ICD, so the donor’s manifest names are never relied on.
The stock WinNative Proton ships only winex11.so, so the Display Server dropdown stays on
X11 with it. Install a Wayland layer from the Contents screen, for example Banner’s
proton-11.0-2.1-arm64ec-wayland-v16.wcp from the Bannerlator Wayland pre-releases
(installs as Proton-11.0-2.1-arm64ec-16), then pick it as the container’s Proton. The
dropdown enables as soon as the selected Proton passes the check.
An x86_64 layer does not qualify, even when it ships a Wayland driver. Its winewayland.so is
a unixlib like any other and Box64 runs it: the compositor gets a connection, a desktop and
windows. But the driver also has to dlopen the Wayland Turnip to hand the game its ICD, and
that Turnip is aarch64, so the pin fails and the session is a desktop that never presents a
frame. Pointing the driver at Box64’s native libwayland-client.so.0 wrapper instead makes
Wine and Turnip share one connection, but the driver then faults at the entry to its event
thread. x86_64 layers therefore stay on X11, where DXVK reaches the GPU through Box64’s Vulkan
wrapper.The files cannot be copied into another Proton. winewayland.so is a Wine unixlib bound to the
win32u it was built against, so a copy taken from a different Proton loads, connects to the
compositor and enumerates its outputs, but creates no window: the session runs with a black screen
and nothing in the log says why. Selecting a Proton that ships its own Wayland driver is the only
supported route.
The compositor needs a Turnip of its own to import the guest’s frames. The stock Vulkan driver has
no VK_EXT_image_drm_format_modifier, so vkCreateDevice fails and nothing is ever presented; a
container or shortcut left on System therefore falls back to the container’s own graphics driver
and then to any installed one, and says so in the log.
When a shortcut or container asks for Wayland and either condition fails, the session starts on
X11 and a toast says so. Before Wine launches on Wayland the launcher creates the runtime
directory, extracts the xkb keymap into it and waits up to eight seconds for the compositor’s
wayland-0 socket, so Wine never starts against a socket that does not exist yet. The check is cached per Wine version and refreshed when contents are
installed or removed.
WAYLAND_DISPLAY=wayland-0 and XDG_RUNTIME_DIR=<app files>/.wayland-rt are exported to the
guest; DISPLAY is not. The Proton’s lib/ directory is placed first on LD_LIBRARY_PATH
because winewayland.so links the Wayland client libraries with unversioned sonames.Software\Wine\Drivers\Graphics = wayland and Wine’s shell desktop
is seeded at the container size; an X11 launch restores both. winex11.drv is disabled
through WINEDLLOVERRIDES for the session so Wine falls through to winewayland.BANNER_WAYLAND_VK_VARIANT selects the bundled Wayland Turnip by GPU generation (a7xx for
Adreno 710/720/722, a8xx for Adreno 8xx). A value set in the container or shortcut
environment wins, as does BANNER_WAYLAND_VK_ICD=<path to icd.json>.GALLIUM_THREAD=0 is exported unless the user set it: Mesa’s threaded GL context has a helper
thread that crashes outside Wine’s signal handling.zwp_text_input_v3; the clipboard is synced both ways.| Variable | Effect |
|---|---|
BANNER_WAYLAND_ZERO_COPY=1 |
Present a fullscreen game window on its own display layer without a copy (also exports BANNER_WSI_AHB=1). |
BANNER_WAYLAND_UBWC=0 |
Advertise linear buffers only; default advertises UBWC (compressed) layouts. |
BANNER_WAYLAND_NO_RENDER_NODE=1 |
Debug: advertise no DRM device in the dma-buf feedback. |
BANNER_WAYLAND_VK_VARIANT / BANNER_WAYLAND_VK_ICD |
Game-side Turnip selection, see above. |
Session logs are written to Android/data/<package>/files/wayland-logs/, one file per session.
The compositor thread is started once per process and kept; a session begins when the display activity attaches its surface and ends when the guest has been terminated. Ending a session disconnects every client, drops the screen surface and resets the compositor’s per-session state, so the next launch, X11 or Wayland, starts clean. A background session that is reattached to a new activity keeps the compositor running and only receives the new surface.
The compositor’s own Turnip driver is the one selected in the graphics driver settings at the time of the first Wayland launch in a process; the game’s driver is chosen per launch.