The emulated tablet kept a single report. Every pointer event (from VNC, or
from another front end) overwrote it, and the guest's next interrupt-IN
transfer took whatever was there. A button press and the matching release
that both arrive before that transfer leave a report with the button up, so
the guest never sees the click; the wheel had the same problem. This happens
when the guest is slow to poll (for example Windows while it enumerates
devices) and when a front end delivers a press and release together, as a
touchpad tap does.
Queue the reports: a change of the buttons or a wheel step is appended (up to
a small bound), a plain move replaces the newest queued report so moves are
not piled up, and each interrupt-IN transfer takes the oldest. The guest then
sees every press, release and wheel step. GET_REPORT still returns the latest
state, and the checkpoint format is unchanged (the queue is not saved; a
restored tablet sends the latest state).
Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev