feat(pointer): virtio tablet as 2nd input dev (driver per-instance VAs, abs/btn decode), input server serves 2 devices on one notif; display software cursor, bar click switches window, presses/releases to front window in its px; k-ui hit-tests (press focuses, release on same presses, field only focuses)

This commit is contained in:
2026-10-28 16:50:20 +01:00
parent 0de13f124d
commit 1401af3d82
22 changed files with 545 additions and 46 deletions

View File

@@ -298,3 +298,36 @@ fn window_keys_raise_home_and_close_only_apps() {
key(&mut s, w::CLOSE_KEY);
assert!(s.slot_for_test(terminal).is_some());
}
#[test]
fn the_pointer_switches_on_the_bar_and_presses_go_to_the_front_window_in_its_pixels() {
use types::input::event::{POINTER_DOWN, POINTER_MOVE, POINTER_UP, pack_point, unpack_point};
let mut s = server();
let t = open(&mut s, 1, b"T");
let app = open(&mut s, 2, b"A");
let notify = CapSlot::new(9).unwrap();
s.handle_call(app, [w::SUBSCRIBE, 0, 0, 0], Some(notify));
s.handle_call(t, [w::SUBSCRIBE, 0, 0, 0], Some(CapSlot::new(10).unwrap()));
// The middle of pixel (x, y), as the input server words a position.
let at = |x: usize, y: usize| pack_point(((2 * x + 1) * 32768 / W) as u16, ((2 * y + 1) * 32768 / H) as u16);
// Moves are the display's: nothing reaches the window.
s.host_mut_for_test().events = vec![[POINTER_MOVE, 0, at(12, 20), 0]];
s.signal(0);
assert_eq!(s.handle_call(app, [w::POLL, 0, 0, 0], None).0[0], 0);
assert_ne!(shown_at(&s, 12, 20), Some(Color::from_raw(0)), "the cursor is drawn where the pointer is");
// A press and release below the bar: the window in front's, in its pixels.
s.host_mut_for_test().events = vec![[POINTER_DOWN, 0, at(12, 20), 0], [POINTER_UP, 0, at(12, 20), 0]];
s.signal(0);
let down = s.handle_call(app, [w::POLL, 0, 0, 0], None).0;
assert_eq!(down[0], POINTER_DOWN);
assert_eq!(unpack_point(down[2]), (12, 20 - BAR_HEIGHT));
assert_eq!(s.handle_call(app, [w::POLL, 0, 0, 0], None).0[0], POINTER_UP);
// A press on the bar, on the first name: that window comes forward.
s.host_mut_for_test().events = vec![[POINTER_DOWN, 0, at(2, 2), 0]];
s.signal(0);
assert_eq!(s.windows_front_for_test(), s.slot_for_test(t));
}
fn shown_at(s: &Srv, x: usize, y: usize) -> Option<Color> {
s.framebuffer().pixel(x, y)
}