Skip to content

Native Wayland clients with render subsurfaces receive no pointer/touch input #85

Description

@Leeestephen

Summary

Anland's native Wayland bridge ignores wl_surface.set_input_region. Its
subsurface hit-test therefore selects the visually topmost buffered subsurface
even when that surface has an explicitly empty input region. Applications that
separate their toolkit toplevel from a GPU render subsurface can display
normally but receive no usable clicks or touches.

This was reproduced consistently with LibreWolf. Simple single-surface GTK3
applications work, which initially makes the problem look toolkit-specific.

Environment

  • Device: Xiaomi Poco F3 (alioth), Snapdragon 870 / Adreno 650
  • Android root: ReSukiSU
  • Container manager: Droidspaces 6.5.5
  • Container: Debian 13 arm64
  • Anland source tested: commit 8e7e2dc
  • Anland configuration: sc_enabled=0, zoom 200%, native Wayland
  • Input sources tested: physical touchscreen and scrcpy UHID mouse
  • Client: LibreWolf 156.0-1, native Wayland (MOZ_ENABLE_WAYLAND=1)

Reproduction

  1. Start Anland and its in-container session normally.
  2. Launch LibreWolf as a native Wayland client.
  3. Open a page containing a large HTML button.
  4. Click or physically touch the button.

Before the compositor patch, pointer movement and keyboard navigation work,
but neither browser chrome nor page controls react to clicks. The DOM click
handler does not fire.

Protocol evidence

The correlated Wayland trace shows two relevant surfaces:

  • wl_surface#43: GTK surface with the xdg_toplevel role
  • wl_surface#37: Firefox/WebRender child subsurface

Firefox calls wl_surface#37.set_input_region(...), then makes surface 37 a
subsurface of surface 43. Anland nevertheless sends wl_pointer.enter and all
button events to surface 37. Firefox's GTK widget logs focus-in on surface 43
but never sees a GDK button press.

Android-side diagnostics and WAYLAND_DEBUG=1 rule out dropped hardware
events: DOWN, BUTTON_PRESS, BUTTON_RELEASE and UP arrive as complete pairs with
valid timestamps, serials and coordinates. The events are simply addressed to
the wrong wl_surface.

Cause in Anland

In services/waylandbridge/awl_surface.c,
surface_set_input_region() is an empty handler. In
services/waylandbridge/awl_subsurface.c, awl_subsurface_hit() walks the
render order and tests only layer buffer bounds. It does not consult the
surface's committed input region.

Consequently a non-input render subsurface wins because it is visually above
the toolkit parent.

Expected behavior

set_input_region(NULL) should restore the default effectively infinite input
region. A supplied wl_region must be snapshotted into pending surface state,
including the distinction between an empty region and the default region, and
become current on the corresponding surface commit. Hit-testing must skip a
surface when the local coordinate is outside its committed input region.

Synchronized subsurfaces should apply the state with their latched commit.
Existing pointer-button and touch-point grabs should remain pinned after the
initial target is selected.

Tested fix

A local native bridge patch was built against commit 8e7e2dc. It:

  • stores wl_region rectangle union/subtraction state;
  • snapshots wl_surface.set_input_region as double-buffered surface state;
  • represents default/infinite and explicitly empty regions distinctly;
  • applies pending input state on direct and synchronized-subsurface commits;
  • checks the committed region during subsurface hit-testing; and
  • leaves the existing post-press/post-touch-down grab behavior unchanged.

After replacing only waylandbridge, the same controlled LibreWolf DOM button
responds immediately to both a UHID mouse click and a physical touchscreen tap.
GTK3 controls continue to work.

Scope

This should also affect other multi-surface native Wayland clients, including
applications with GPU/video subsurfaces or non-input overlays. It is separate
from the observed Android AHardwareBuffer allocator crash in some clients;
that renderer abort is not fixed by this input-routing change.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions