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

            Bug ID: 520464
           Summary: EIS backend silently drops the keyboard device when a
                    client binds Keyboard alongside Pointer or
                    PointerAbsolute
    Classification: Plasma
           Product: kwin
      Version First 6.6.5
       Reported In:
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: wayland-generic
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

When a libei client binds Keyboard together with either Pointer or
PointerAbsolute in one ei_seat.bind call, KWin's EIS backend creates the
pointer device but never creates a keyboard device. The SeatAdded event comes
through, the client's bind is acknowledged, and then only the pointer-class
DeviceAdded arrives. Any subsequent attempt to send keyboard input fails
because the client has no ei_keyboard interface. Binding Keyboard alone, or
alongside Button or Scroll, produces the expected keyboard device every time.
The trigger is specifically Keyboard + Pointer or Keyboard + PointerAbsolute in
a single bind.

Reproduced on Plasma 6.6.5, KWin 6.6.5, libei 1.5.0, xdg-desktop-portal-kde
6.6.5, Arch Linux.

## Reproduction

Clone https://github.com/cushycush/wdotool, check out branch
`debug/libei-events`, and build with `cargo build --release`. The binary has a
`WDOTOOL_BIND` env var that takes a comma list of caps (kbd, ptr, abs, btn,
scroll) to pass to ei_seat.bind. Wipe the cached portal token between runs so
each one pops a fresh consent dialog:

    rm -f ~/.local/state/wdotool/portal.token
    WDOTOOL_BIND=kbd,ptr RUST_LOG=info ./target/release/wdotool key a

Accept the RemoteDesktop consent dialog when it appears.

## What I see

Only a pointer DeviceAdded comes back. No keyboard.

    INFO libei portal start: device types granted granted=Keyboard | Pointer
    INFO libei SeatAdded seat_name="wdotool seat" bound=Pointer | Keyboard
    INFO libei DeviceAdded name="wdotool eis pointer" caps=[pointer, button,
scroll]
    INFO libei DeviceResumed has_kbd=false has_ptr=true ready=true

`wdotool key a` then errors with "no keyboard device from EIS".

## What I expect

Two DeviceAdded events for the bind set Keyboard | Pointer: one pointer, one
keyboard. That is what happens for every other bind set I tested.

## Triangulation

| Bind set                            | Keyboard device created? |
| ----------------------------------- | ------------------------ |
| Keyboard                            | yes                      |
| Keyboard + Button                   | yes                      |
| Keyboard + Scroll                   | yes                      |
| Keyboard + Pointer                  | no                       |
| Keyboard + PointerAbsolute          | no                       |
| Keyboard + Ptr + Abs + Btn + Scroll | no                       |

So Pointer or PointerAbsolute in the same bind as Keyboard is what makes the
keyboard disappear. Button or Scroll alongside Keyboard is fine. The fact that
Button and Scroll (which get configured on the pointer/absolute device, rather
than as their own devices) coexist with Keyboard fine, but Pointer and
PointerAbsolute (which each trigger their own device creation) cause the drop,
suggests the bug is in how libeis or KWin tracks per-device state across
back-to-back eis_device_add calls inside a single SEAT_BIND handler. The
handler at src/plugins/eis/eiscontext.cpp around the EIS_EVENT_SEAT_BIND case
looks correct on inspection, and createKeyboard at
src/plugins/eis/eisbackend.cpp works in isolation, so I did not get further
than that.

## Workaround on the client side

I now bind keyboard in a separate ei_seat.bind call from pointer/absolute. That
produces all the expected devices, but it goes against what the protocol nudges
you toward (one bind that covers everything), and any other portal-aware libei
client built against this KWin will hit the same drop unless it splits its
binds too.

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

Reply via email to