Skip to content

phase-3: surface wl_display + wl_compositor + wl_subcompositor + EGL display to webkit engine #151

@mxaddict

Description

@mxaddict

Sub-task of #145 (re-scoped 2026-05-17 — see comment).

apps/buffr-app currently owns winit's wl_display + wl_surface. Phase 3 needs to share those with the WebKit engine so the engine can create its own `wl_surface` as a child via wl_subsurface from the SAME wl_display (cross-client subsurface is impossible).

Scope

  1. Extract Wayland handles in apps/buffr-app at startup:

    • From winit `Window::display_handle`: `RawDisplayHandle::Wayland(WaylandDisplayHandle).display` → `wl_display`.
    • From `Window::window_handle`: `RawWindowHandle::Wayland(WaylandWindowHandle).surface` → parent `wl_surface`.
    • Bind `wl_compositor` via wl_registry: `wl_display_get_registry` → listener catches `global` events → bind `wl_compositor` v6+.
    • Bind `wl_subcompositor` similarly.
    • Create EGL platform display: `eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, wl_display, NULL)` → `EGLDisplay`. (Only needed if WebKit's EGL rendering needs platform integration; verify in #145b.)
  2. Cache all four handles on AppState as opaque pointers (`*mut wl_display`, etc., wrapped in `Send`-marked newtypes).

  3. Pass to WebKitEngine via an extended setter. Options:

    • Extend BackendOpenOptions with new fields (couples to all backends). Too invasive.
    • Add a webkit-specific setter `engine.set_native_wayland_handles(...)` post-construction. Same pattern as `set_edit_sink`.
    • Carry through the existing `set_native_parent` (RawWindowHandle, NativeRect) by extending NativeRect with optional compositor handles. Hacky.

    Recommend option 2 — webkit-specific setter on WebKitEngine. Apps calls right after engine construction in the webkit branch.

Implementation notes

  • Use the `wayland-client` Rust crate (or `wayland-sys` for raw FFI) for the wl_registry roundtrip. `wayland-sys` is lighter; `wayland-client` higher-level but pulls smithay code.
  • The wl_display from winit must NOT be `wl_display_disconnect`ed by the engine — apps owns its lifetime.
  • All four pointers go through to BuffrDisplayWayland (#145b) which constructs a WPEDisplay subclass that uses them.

Out of scope

  • `BuffrDisplayWayland` itself (#145b).
  • `BuffrViewWayland` render_buffer bridge (#145c).

Acceptance

  • Apps logs the four bound handles at startup.
  • WebKitEngine receives them via the setter (logged in engine).
  • No build errors on X11 or headless (Wayland-only code paths gated).

Reference

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestparkedDormant — feature kept in backlog but not actively worked on

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions