https://bugs.kde.org/show_bug.cgi?id=528033

            Bug ID: 528033
           Summary: Wayland: pointer input not routed to a wl_subsurface
                    when the pointer moves onto it from the parent surface
    Classification: Plasma
           Product: kwin
      Version First 6.8.2
       Reported In:
          Platform: unspecified
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: wayland-generic
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

# Wayland: pointer input not routed to a wl_subsurface when the pointer moves
onto it from the parent surface

## Summary

On KWin 6.8.2 (Wayland), a `wl_subsurface` that lies inside the parent surface
does not receive pointer input if the pointer enters the window over the parent
surface first and then moves onto the subsurface. The pointer focus stays on
the
toplevel surface, so clicks are delivered to the parent (e.g. the web page
behind a Chromium popup) instead of the subsurface.

If the pointer enters the window already over the subsurface (e.g. a subsurface
that covers the whole parent), everything works: `wl_pointer.enter` is sent to
the subsurface and clicks arrive there.

This breaks Chromium/Chrome popups on Wayland: the autofill dropdown and
permission bubbles are `wl_subsurface`s, and they are completely unclickable
when the pointer moves from the page onto them. `WAYLAND_DEBUG=1` trace from
Chrome is attached.

## Steps to reproduce

1. Build the attached minimal client (`subsurface-input.c` + `build.sh`, needs
   `wayland-client` and `wayland-scanner`):
   ```
   ./build.sh && ./subsurface-input --region
   ```
   It creates a 400×300 `xdg_toplevel` and a 380×280 `wl_subsurface` at (10,10)
   with an explicit input region covering the child, in desync mode.
2. Enter the window from the bottom edge (10 px of parent surface) and move the
   pointer into the green subsurface.
3. Click inside the subsurface.

## Actual behaviour

Every `wl_pointer` event is delivered to the toplevel surface. The client
prints
`ENTER TOPLEVEL` / `BUTTON TOPLEVEL` even when the pointer is well inside the
subsurface; the child never receives `wl_pointer.enter`:

```
mapped: toplevel 400x300, child 380x280 at (10,10), mode=desync
input region: explicit rect
ENTER  TOPLEVEL               at (193.8, 299.1)
MOTION TOPLEVEL               at (197.7, 272.1)
MOTION TOPLEVEL               at (200.7, 241.6)
MOTION TOPLEVEL               at (203.6, 216.6)   <- inside the child (10..390,
10..290)
BUTTON TOPLEVEL               button=272 pressed
BUTTON TOPLEVEL               button=272 released
```

Same result with `set_input_region(NULL)` (infinite region), so it is not about
the input region.

Control experiment: make the subsurface cover the whole parent (400×300 at
0,0) and enter the window directly over it — then the child does get input:

```
mapped: toplevel 400x300, child 400x300 at (0,0), mode=desync
input region: nil (infinite)
ENTER  CHILD (subsurface)     at (132.2, 291.0)
BUTTON CHILD (subsurface)     button=272 pressed
```

## Expected behaviour

Moving the pointer from the parent surface onto a subsurface should update the
pointer focus and send `wl_pointer.enter` for the subsurface; clicks inside it
should be delivered to the subsurface.

## Additional information

- Reproduced on: KWin 6.8.2, Plasma 6.8.2, Qt 6.12.0, wayland 1.26.0,
  Mesa 26.2.5, Arch/CachyOS, kernel 7.3.0, Intel Meteor Lake (Arc Graphics),
  single output 3072×1920, scale 2.
- Also observed with Chrome 156.0.8078.73 on KWin 6.8.1 (permission/translate
  bubbles created with `OzoneBubblesUsePlatformWidgets` and the autofill
  dropdown).
- The two pointer/subsurface fixes from 2026-10-08
  (`a016d6cc` "wayland/seat: actually update the effective pointer focus
  surface", `239e16c0` "fix implicit pointer grabs on subsurfaces") are already
  included in 6.8.2 and do not fix this case.
- No button is pressed while the pointer moves onto the subsurface, so the
  implicit-grab early-return in `SeatInterfacePrivate::updatePointerFocus()`
  should not apply.

## See also

- Bug 522526 looks related but is a different issue: it requires two monitors
  with different resolutions aligned by their bottom edge, the popup is never
  rendered at all, and it also happens with XWayland. In the case reported here
  the popup is visible and native-X11 (XWayland) works fine.

## Attachments

- `subsurface-input.c`, `build.sh`, `README.md` — minimal client
- `log-inset-explicit-region.txt` — failing case (child inset, explicit region)
- `log-inset-nil-region.txt` — failing case (child inset, `NULL` region)
- `log-full-child.txt` — control case that works
- `chrome-wayland-popup-trace.txt` — Chrome autofill popup, `WAYLAND_DEBUG=1`

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to