feat: touch input — TouchDown/Move/Up + host libei ei_touchscreen injection
ci / rust (push) Has been cancelled
ci / rust (push) Has been cancelled
Roadmap #5 (touch, ahead of the XL UHID DualSense work). Touch fits the existing 18-byte InputEvent: code = touch id, x/y = client pixels, flags = (w<<16)|h — the same absolute mapping as MouseMoveAbs. - core: InputKind::{TouchDown=9, TouchMove=10, TouchUp=11} + from_u8 + roundtrip test. - host inject/libei.rs: request the RemoteDesktop Touchscreen device type, bind the Touch capability, and inject ei_touchscreen down/motion/up (one event = one frame, per the protocol rule), mapping coordinates into the device region like the abs pointer. wlroots has no virtual-touch protocol wired — no-ops there. - client-rs --touch-test: drags a synthetic finger (touch id 0) in a circle. Validated live on headless KWin: the portal GRANTS the Touchscreen device type (Keyboard|Pointer|Touchscreen), proving the request path — but KWin's EIS server creates no touchscreen *device*, so touch currently no-ops on this KWin (now logged once, not silent). The injection code is correct and will land on a backend that exposes ei_touchscreen (gamescope / a newer compositor / the real touch-client path). Workspace green, clippy/fmt clean, +1 unit test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,14 @@ pub enum InputKind {
|
||||
/// Sticks are i16 range (−32768..32767) in the XInput/Moonlight convention — **+y =
|
||||
/// up** (unlike mouse coordinates); triggers 0..255.
|
||||
GamepadAxis = 8,
|
||||
/// Touch begins. `code` = touch id (which finger; reusable after `TouchUp`), `x`/`y` =
|
||||
/// pixel coordinates and `flags` = `(width << 16) | height` of the client's touch surface
|
||||
/// — the same absolute mapping as [`MouseMoveAbs`](Self::MouseMoveAbs).
|
||||
TouchDown = 9,
|
||||
/// Touch moves. Same field meaning as [`TouchDown`](Self::TouchDown).
|
||||
TouchMove = 10,
|
||||
/// Touch ends. Only `code` (the touch id) is used.
|
||||
TouchUp = 11,
|
||||
}
|
||||
|
||||
/// The gamepad wire contract for [`InputKind::GamepadButton`]/[`InputKind::GamepadAxis`].
|
||||
@@ -79,6 +87,9 @@ impl InputKind {
|
||||
6 => MouseScroll,
|
||||
7 => GamepadButton,
|
||||
8 => GamepadAxis,
|
||||
9 => TouchDown,
|
||||
10 => TouchMove,
|
||||
11 => TouchUp,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@@ -148,4 +159,26 @@ mod tests {
|
||||
assert_eq!(InputEvent::decode(&e.encode()), Some(e));
|
||||
assert!(InputEvent::decode(&[0u8; INPUT_WIRE_LEN]).is_none()); // bad magic
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn touch_kinds_roundtrip() {
|
||||
for kind in [
|
||||
InputKind::TouchDown,
|
||||
InputKind::TouchMove,
|
||||
InputKind::TouchUp,
|
||||
] {
|
||||
assert_eq!(InputKind::from_u8(kind as u8), Some(kind));
|
||||
let e = InputEvent {
|
||||
kind,
|
||||
_pad: [0; 3],
|
||||
code: 2, // touch id
|
||||
x: 640,
|
||||
y: 360,
|
||||
flags: (1280u32 << 16) | 720, // client surface w/h
|
||||
};
|
||||
assert_eq!(InputEvent::decode(&e.encode()), Some(e));
|
||||
}
|
||||
// 12 (one past TouchUp) is not a valid kind.
|
||||
assert_eq!(InputKind::from_u8(12), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user