Feat/wayland driver binding
Summary
Adds LVGL's native Wayland driver as a working alternative to the SDL
driver, and fixes a regression that's been silently keeping every LVGL
desktop window driver (SDL included) out of the Python bindings entirely.
lv_sdl_window_create() can segfault deep inside the proprietary NVIDIA
driver as soon as a real window is presented, on Wayland sessions with an
NVIDIA GPU. This is #46, filed in 2019 and auto-closed stale in 2020
without a fix - I hit it firsthand and confirmed it's still present today,
5+ years later. The maintainers' own diagnosis at the time: this binding's
SDL driver deliberately runs SDL on MicroPython's own thread (for LVGL
binding thread-safety), unlike the standalone lv_drivers SDL simulator,
which refreshes on its own dedicated thread and doesn't hit the bug.
LVGL's native Wayland driver (lvgl/src/drivers/wayland) sidesteps the
whole crash class: it presents via wl_shm and never creates a GL/EGL
context at all. It's already upstream in LVGL, just never wired into this
binding's build or exposed to Python - both are fixed here.
While wiring Wayland up, I found gen_mpy.py hasn't been able to see any
desktop window driver - SDL included - since 3f32386 (2026-05-02) switched
its input from lvgl.h (which pulls in src/drivers/lv_drivers.h) to
lvgl_private.h (which only pulls in _private.h counterparts for the
libinput/evdev drivers). lv.sdl_window_create etc. have simply not
existed as Python attributes since then, regardless of LV_USE_SDL - this
also silently broke this repo's own tests/testdisplay.py's interactive
mode. Fixed by gen/lv_mpy_drivers.h, which gen_mpy now parses instead: it
pulls in lvgl_private.h and src/drivers/lv_drivers.h, so any driver
enabled in lv_conf.h gets bound the same way widgets already are.
gen/lv_mpy_drivers.c adds a binding-friendly
lv_wayland_window_create_simple() wrapper, since gen_mpy can't bind
lv_wayland_window_create()'s close-callback parameter (no
user_data-carrying struct argument for it to hook into).
micropython.mk autodetects wayland-client/wayland-cursor/xkbcommon
via pkg-config, the same pattern SDL already uses, and generates the
xdg-shell protocol glue at build time via wayland-scanner into
$(BUILD) - nothing checked into the lvgl submodule. LV_COLOR_DEPTH is
forced to 32 only when Wayland is actually compiled in, since
lv_wayland_window_create() hangs rather than failing fast on a
compositor that doesn't advertise wl_shm RGB565 support (optional
per-spec, unlike XRGB8888/ARGB8888).
This is based on #411, which this build needed to even link against a
current MicroPython. Expecting that one to land first.
Testing
Rather than duplicating tests/display/tests/indev per driver,
testdisplay.py/testrunner.py/lv_utils.py gain a DRIVER selector
("sdl"/"wayland", or the LV_MP_TEST_DRIVER env var), so the existing
suites run against either driver unchanged. Verified
tests/display/basic.py against Wayland via a headless weston
compositor - output matches the existing .exp byte for byte, no new
expected-output file needed. CI installs the Wayland build deps and
weston, and runs tests/display against Wayland in a new job step.
Doesn't attempt to fix the underlying NVIDIA/SDL bug itself (#46) - a
proprietary-driver issue outside this repo's control - or the window
decorations abort (lv_wl_window_decorations.c, unrelated, left at
upstream's own default of off).
Generative AI
I used generative AI tools when creating this PR, but a human has checked
the code and is responsible for the code and the description above.
Summary by cubic
Adds LVGL’s Wayland window driver as a safe alternative to SDL on Linux, restores desktop driver APIs to the Python bindings, and ensures compatibility with MicroPython 1.29.
-
New Features
- Wayland driver binding:
lv.wayland_window_create_simple(...),lv.wayland_pointer_create(),lv.wayland_keyboard_create(),lv.wayland_timer_handler(),lv.wayland_window_is_open(). - Auto-enable when
wayland-client,wayland-cursor,xkbcommon,wayland-scanner, andwayland-protocolsare found viapkg-config; generatesxdg-shellglue at build time. - Event loop supports a driver-specific timer via
handler_cbfor Wayland. - Tests/CI can run against
waylandviaLV_MP_TEST_DRIVER; CI uses headlessweston. - Sets
LV_COLOR_DEPTH=32when Wayland is compiled to ensure a supportedwl_shmformat.
- Wayland driver binding:
-
Bug Fixes
- Restores SDL/desktop driver bindings by feeding
gen_mpygen/lv_mpy_drivers.h(includessrc/drivers/lv_drivers.h) and adds alv_wayland_window_create_simple()wrapper to avoid an unbindable close-callback. - Builds with MicroPython 1.29 by using
mp_obj_int_to_bytes()with version guards.
- Restores SDL/desktop driver bindings by feeding