From 145e4dbc24a99120c54859b0b017e16ef45bdf69 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 26 May 2022 12:25:59 +0200 Subject: [PATCH] wayland: add times to all input events --- src/backend.rs | 41 +++++++++++++---- src/backends/metal.rs | 14 +++++- src/backends/metal/input.rs | 30 +++++++++--- src/backends/x.rs | 51 +++++++++++++-------- src/ifs/ipc/wl_data_device.rs | 4 +- src/ifs/wl_seat.rs | 2 + src/ifs/wl_seat/event_handling.rs | 69 +++++++++++++++++++--------- src/ifs/wl_seat/pointer_owner.rs | 21 +++++---- src/ifs/wl_seat/wl_pointer.rs | 2 + src/ifs/wl_surface.rs | 11 +++-- src/it/test_backend.rs | 76 ++++++++++++++++++++----------- src/time.rs | 4 ++ src/tree.rs | 8 +++- src/tree/container.rs | 1 + src/tree/float.rs | 1 + src/tree/output.rs | 1 + 16 files changed, 235 insertions(+), 101 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 90de80cf..a53829b6 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -150,8 +150,17 @@ pub enum AxisSource { #[derive(Debug)] pub enum InputEvent { - Key(u32, KeyState), - ConnectorPosition(ConnectorId, Fixed, Fixed), + Key { + time_usec: u64, + key: u32, + state: KeyState, + }, + ConnectorPosition { + time_usec: u64, + connector: ConnectorId, + x: Fixed, + y: Fixed, + }, Motion { time_usec: u64, dx: Fixed, @@ -159,13 +168,29 @@ pub enum InputEvent { dx_unaccelerated: Fixed, dy_unaccelerated: Fixed, }, - Button(u32, KeyState), + Button { + time_usec: u64, + button: u32, + state: KeyState, + }, - Axis(Fixed, ScrollAxis), - AxisSource(AxisSource), - AxisStop(ScrollAxis), - AxisDiscrete(i32, ScrollAxis), - Frame, + Axis { + dist: Fixed, + axis: ScrollAxis, + }, + AxisSource { + source: AxisSource, + }, + AxisStop { + axis: ScrollAxis, + }, + AxisDiscrete { + dist: i32, + axis: ScrollAxis, + }, + AxisFrame { + time_usec: u64, + }, } pub enum DrmEvent { diff --git a/src/backends/metal.rs b/src/backends/metal.rs index f3745d93..2e2c651d 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -25,6 +25,7 @@ use { logind::{LogindError, Session}, render::RenderError, state::State, + time::now_usec, udev::{Udev, UdevError, UdevMonitor}, utils::{ clonecell::{CloneCell, UnsafeCellCloneSafe}, @@ -341,11 +342,20 @@ impl MetalInputDevice { } fn pre_pause(&self) { + let time_usec = now_usec(); for (key, _) in self.pressed_keys.take() { - self.event(InputEvent::Key(key, KeyState::Released)); + self.event(InputEvent::Key { + time_usec, + key, + state: KeyState::Released, + }); } for (button, _) in self.pressed_buttons.take() { - self.event(InputEvent::Button(button, KeyState::Released)); + self.event(InputEvent::Button { + time_usec, + button, + state: KeyState::Released, + }); } } } diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index 95014105..e59fbcc7 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -119,7 +119,11 @@ impl MetalBackend { } KeyState::Released }; - dev.event(InputEvent::Key(event.key(), state)); + dev.event(InputEvent::Key { + time_usec: event.time_usec(), + key: event.key(), + state, + }); } fn handle_pointer_axis(self: &Rc, event: LibInputEvent, source: AxisSource) { @@ -132,7 +136,7 @@ impl MetalBackend { ), (LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical), ]; - dev.event(InputEvent::AxisSource(source)); + dev.event(InputEvent::AxisSource { source }); for (axis, sa) in axes { if !event.has_axis(axis) { continue; @@ -142,17 +146,25 @@ impl MetalBackend { _ => event.scroll_value(axis), }; if scroll == 0.0 { - dev.event(InputEvent::AxisStop(sa)); + dev.event(InputEvent::AxisStop { axis: sa }); } else { if source == AxisSource::Wheel { let scroll_discrete = scroll / ONE_TWENTRY; - dev.event(InputEvent::AxisDiscrete(scroll_discrete as _, sa)); + dev.event(InputEvent::AxisDiscrete { + dist: scroll_discrete as _, + axis: sa, + }); scroll = PX_PER_SCROLL * scroll_discrete; } - dev.event(InputEvent::Axis(Fixed::from_f64(scroll), sa)); + dev.event(InputEvent::Axis { + dist: Fixed::from_f64(scroll), + axis: sa, + }); } } - dev.event(InputEvent::Frame); + dev.event(InputEvent::AxisFrame { + time_usec: event.time_usec(), + }); } fn handle_pointer_button(self: &Rc, event: LibInputEvent) { @@ -168,7 +180,11 @@ impl MetalBackend { } KeyState::Released }; - dev.event(InputEvent::Button(event.button(), state)); + dev.event(InputEvent::Button { + time_usec: event.time_usec(), + button: event.button(), + state, + }); } fn handle_pointer_motion(self: &Rc, event: LibInputEvent) { diff --git a/src/backends/x.rs b/src/backends/x.rs index 6acc86a7..86966b6b 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -12,6 +12,7 @@ use { ifs::wl_seat::PX_PER_SCROLL, render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture}, state::State, + time::now_usec, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, queue::AsyncQueue, syncqueue::SyncQueue, @@ -761,13 +762,17 @@ impl XBackend { 7 => (ScrollAxis::Horizontal, 1), _ => unreachable!(), }; - seat.mouse_event(InputEvent::AxisSource(AxisSource::Wheel)); - seat.mouse_event(InputEvent::AxisDiscrete(val, axis)); - seat.mouse_event(InputEvent::Axis( - Fixed::from_f64(val as f64 * PX_PER_SCROLL), + seat.mouse_event(InputEvent::AxisSource { + source: AxisSource::Wheel, + }); + seat.mouse_event(InputEvent::AxisDiscrete { dist: val, axis }); + seat.mouse_event(InputEvent::Axis { + dist: Fixed::from_f64(val as f64 * PX_PER_SCROLL), axis, - )); - seat.mouse_event(InputEvent::Frame); + }); + seat.mouse_event(InputEvent::AxisFrame { + time_usec: now_usec(), + }); } } else { const BTN_LEFT: u32 = 0x110; @@ -781,7 +786,11 @@ impl XBackend { 3 => BTN_RIGHT, n => BTN_SIDE + n - 8, }; - seat.mouse_event(InputEvent::Button(button, state)); + seat.mouse_event(InputEvent::Button { + time_usec: now_usec(), + button, + state, + }); } } Ok(()) @@ -794,7 +803,11 @@ impl XBackend { ) -> Result<(), XBackendError> { let event: XiKeyPress = event.parse()?; if let Some(seat) = self.seats.get(&event.deviceid) { - seat.kb_event(InputEvent::Key(event.detail - 8, state)); + seat.kb_event(InputEvent::Key { + time_usec: now_usec(), + key: event.detail - 8, + state, + }); } Ok(()) } @@ -824,11 +837,12 @@ impl XBackend { self.outputs.get(&event.event), self.mouse_seats.get(&event.deviceid), ) { - seat.mouse_event(InputEvent::ConnectorPosition( - win.id, - Fixed::from_1616(event.event_x), - Fixed::from_1616(event.event_y), - )); + seat.mouse_event(InputEvent::ConnectorPosition { + time_usec: now_usec(), + connector: win.id, + x: Fixed::from_1616(event.event_x), + y: Fixed::from_1616(event.event_y), + }); } Ok(()) } @@ -842,11 +856,12 @@ impl XBackend { (Some(a), Some(b)) => (a, b), _ => return Ok(()), }; - seat.mouse_event(InputEvent::ConnectorPosition( - win.id, - Fixed::from_1616(event.event_x), - Fixed::from_1616(event.event_y), - )); + seat.mouse_event(InputEvent::ConnectorPosition { + time_usec: now_usec(), + connector: win.id, + x: Fixed::from_1616(event.event_x), + y: Fixed::from_1616(event.event_y), + }); Ok(()) } diff --git a/src/ifs/ipc/wl_data_device.rs b/src/ifs/ipc/wl_data_device.rs index 65207396..958c2e2a 100644 --- a/src/ifs/ipc/wl_data_device.rs +++ b/src/ifs/ipc/wl_data_device.rs @@ -115,11 +115,11 @@ impl WlDataDevice { } } - pub fn send_motion(&self, x: Fixed, y: Fixed) { + pub fn send_motion(&self, time_usec: u64, x: Fixed, y: Fixed) { if !self.data.is_xwm { self.client.event(Motion { self_id: self.id, - time: 0, + time: (time_usec / 1000) as _, x, y, }) diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 45c38ccb..0daf49c8 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -116,6 +116,7 @@ pub struct WlSeatGlobal { move_: Cell, move_start_pos: Cell<(Fixed, Fixed)>, extents_start_pos: Cell<(i32, i32)>, + pos_time_usec: Cell, pos: Cell<(Fixed, Fixed)>, pointer_stack: RefCell>>, pointer_stack_modified: Cell, @@ -163,6 +164,7 @@ impl WlSeatGlobal { move_: Cell::new(false), move_start_pos: Cell::new((Fixed(0), Fixed(0))), extents_start_pos: Cell::new((0, 0)), + pos_time_usec: Cell::new(0), pos: Cell::new((Fixed(0), Fixed(0))), pointer_stack: RefCell::new(vec![]), pointer_stack_modified: Cell::new(false), diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index b71f6131..6808ca0f 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -167,8 +167,17 @@ impl NodeSeatState { impl WlSeatGlobal { pub fn event(self: &Rc, event: InputEvent) { match event { - InputEvent::Key(k, s) => self.key_event(k, s), - InputEvent::ConnectorPosition(o, x, y) => self.connector_position_event(o, x, y), + InputEvent::Key { + time_usec, + key, + state, + } => self.key_event(time_usec, key, state), + InputEvent::ConnectorPosition { + time_usec, + connector, + x, + y, + } => self.connector_position_event(time_usec, connector, x, y), InputEvent::Motion { dx, dy, @@ -176,18 +185,23 @@ impl WlSeatGlobal { dy_unaccelerated, time_usec, } => self.motion_event(time_usec, dx, dy, dx_unaccelerated, dy_unaccelerated), - InputEvent::Button(b, s) => self.pointer_owner.button(self, b, s), + InputEvent::Button { + time_usec, + button, + state, + } => self.pointer_owner.button(self, time_usec, button, state), - InputEvent::AxisSource(s) => self.pointer_owner.axis_source(s), - InputEvent::AxisDiscrete(d, a) => self.pointer_owner.axis_discrete(d, a), - InputEvent::Axis(d, a) => self.pointer_owner.axis(d, a), - InputEvent::AxisStop(d) => self.pointer_owner.axis_stop(d), - InputEvent::Frame => self.pointer_owner.frame(self), + InputEvent::AxisSource { source } => self.pointer_owner.axis_source(source), + InputEvent::AxisDiscrete { dist, axis } => self.pointer_owner.axis_discrete(dist, axis), + InputEvent::Axis { dist, axis } => self.pointer_owner.axis(dist, axis), + InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis), + InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec), } } fn connector_position_event( self: &Rc, + time_usec: u64, connector: ConnectorId, mut x: Fixed, mut y: Fixed, @@ -200,7 +214,7 @@ impl WlSeatGlobal { let pos = output.node.global.pos.get(); x += Fixed::from_int(pos.x1()); y += Fixed::from_int(pos.y1()); - self.set_new_position(x, y); + self.set_new_position(time_usec, x, y); } fn motion_event( @@ -249,10 +263,10 @@ impl WlSeatGlobal { y = y.apply_fract(y_int); } } - self.set_new_position(x, y); + self.set_new_position(time_usec, x, y); } - fn key_event(&self, key: u32, state: KeyState) { + fn key_event(&self, time_usec: u64, key: u32, state: KeyState) { let (state, xkb_dir) = { let mut pk = self.pressed_keys.borrow_mut(); match state { @@ -290,7 +304,7 @@ impl WlSeatGlobal { } let node = self.keyboard_node.get(); if shortcuts.is_empty() { - node.node_on_key(self, key, state); + node.node_on_key(self, time_usec, key, state); } else if let Some(config) = self.state.config.get() { for shortcut in shortcuts { config.invoke_shortcut(self.id(), &shortcut); @@ -461,7 +475,8 @@ impl WlSeatGlobal { // client.flush(); } - fn set_new_position(self: &Rc, x: Fixed, y: Fixed) { + fn set_new_position(self: &Rc, time_usec: u64, x: Fixed, y: Fixed) { + self.pos_time_usec.set(time_usec); self.pos.set((x, y)); if let Some(cursor) = self.cursor.get() { cursor.set_position(x.round_down(), y.round_down()); @@ -499,6 +514,7 @@ impl WlSeatGlobal { pub fn button_surface( self: &Rc, surface: &Rc, + time_usec: u64, button: u32, state: KeyState, serial: u32, @@ -507,7 +523,8 @@ impl WlSeatGlobal { KeyState::Released => (wl_pointer::RELEASED, false), KeyState::Pressed => (wl_pointer::PRESSED, true), }; - self.surface_pointer_event(0, surface, |p| p.send_button(serial, 0, button, state)); + let time = (time_usec / 1000) as u32; + self.surface_pointer_event(0, surface, |p| p.send_button(serial, time, button, state)); self.surface_pointer_frame(surface); if pressed { if let Some(node) = surface.get_focus_node(self.id) { @@ -528,6 +545,7 @@ impl WlSeatGlobal { }; self.surface_pointer_event(since, surface, |p| p.send_axis_source(source)); } + let time = (event.time_usec.get() / 1000) as _; for i in 0..1 { if let Some(delta) = event.discrete[i].get() { self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| { @@ -535,11 +553,11 @@ impl WlSeatGlobal { }); } if let Some(delta) = event.axis[i].get() { - self.surface_pointer_event(0, surface, |p| p.send_axis(0, i as _, delta)); + self.surface_pointer_event(0, surface, |p| p.send_axis(time, i as _, delta)); } if event.stop[i].get() { self.surface_pointer_event(AXIS_STOP_SINCE_VERSION, surface, |p| { - p.send_axis_stop(0, i as _) + p.send_axis_stop(time, i as _) }); } } @@ -550,7 +568,8 @@ impl WlSeatGlobal { // Motion callbacks impl WlSeatGlobal { pub fn motion_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) { - self.surface_pointer_event(0, n, |p| p.send_motion(0, x, y)); + let time = (self.pos_time_usec.get() / 1000) as u32; + self.surface_pointer_event(0, n, |p| p.send_motion(time, x, y)); self.surface_pointer_frame(n); } } @@ -638,9 +657,10 @@ impl WlSeatGlobal { // Key callbacks impl WlSeatGlobal { - pub fn key_surface(&self, surface: &WlSurface, key: u32, state: u32) { + pub fn key_surface(&self, surface: &WlSurface, time_usec: u64, key: u32, state: u32) { let serial = surface.client.next_serial(); - self.surface_kb_event(0, surface, |k| k.send_key(serial, 0, key, state)); + let time = (time_usec / 1000) as _; + self.surface_kb_event(0, surface, |k| k.send_key(serial, time, key, state)); } } @@ -708,10 +728,17 @@ impl WlSeatGlobal { // surface.client.flush(); } - pub fn dnd_surface_motion(&self, surface: &WlSurface, dnd: &Dnd, x: Fixed, y: Fixed) { + pub fn dnd_surface_motion( + &self, + surface: &WlSurface, + dnd: &Dnd, + time_usec: u64, + x: Fixed, + y: Fixed, + ) { if dnd.src.is_some() || surface.client.id == dnd.client.id { self.for_each_data_device(0, surface.client.id, |dd| { - dd.send_motion(x, y); + dd.send_motion(time_usec, x, y); }) } // surface.client.flush(); diff --git a/src/ifs/wl_seat/pointer_owner.rs b/src/ifs/wl_seat/pointer_owner.rs index 3a4ea8e7..bc283150 100644 --- a/src/ifs/wl_seat/pointer_owner.rs +++ b/src/ifs/wl_seat/pointer_owner.rs @@ -31,8 +31,8 @@ impl Default for PointerOwnerHolder { } impl PointerOwnerHolder { - pub fn button(&self, seat: &Rc, button: u32, state: KeyState) { - self.owner.get().button(seat, button, state) + pub fn button(&self, seat: &Rc, time_usec: u64, button: u32, state: KeyState) { + self.owner.get().button(seat, time_usec, button, state) } pub fn axis_source(&self, axis_source: AxisSource) { @@ -51,7 +51,8 @@ impl PointerOwnerHolder { self.pending_scroll.stop[axis as usize].set(true); } - pub fn frame(&self, seat: &Rc) { + pub fn frame(&self, seat: &Rc, time_usec: u64) { + self.pending_scroll.time_usec.set(time_usec); let pending = self.pending_scroll.take(); if let Some(node) = self.owner.get().axis_node(seat) { node.node_on_axis_event(seat, &pending); @@ -122,7 +123,7 @@ impl PointerOwnerHolder { } trait PointerOwner { - fn button(&self, seat: &Rc, button: u32, state: KeyState); + fn button(&self, seat: &Rc, time_usec: u64, button: u32, state: KeyState); fn axis_node(&self, seat: &Rc) -> Option>; fn apply_changes(&self, seat: &Rc); fn start_drag( @@ -158,7 +159,7 @@ struct DndPointerOwner { } impl PointerOwner for DefaultPointerOwner { - fn button(&self, seat: &Rc, button: u32, state: KeyState) { + fn button(&self, seat: &Rc, time_usec: u64, button: u32, state: KeyState) { if state != KeyState::Pressed { return; } @@ -173,7 +174,7 @@ impl PointerOwner for DefaultPointerOwner { serial, })); pn.node_seat_state().add_pointer_grab(seat); - pn.node_on_button(seat, button, state, serial); + pn.node_on_button(seat, time_usec, button, state, serial); } fn axis_node(&self, seat: &Rc) -> Option> { @@ -280,7 +281,7 @@ impl PointerOwner for DefaultPointerOwner { } impl PointerOwner for GrabPointerOwner { - fn button(&self, seat: &Rc, button: u32, state: KeyState) { + fn button(&self, seat: &Rc, time_usec: u64, button: u32, state: KeyState) { match state { KeyState::Released => { self.buttons.remove(&button); @@ -300,7 +301,7 @@ impl PointerOwner for GrabPointerOwner { let serial = seat.state.next_serial(self.node.node_client().as_deref()); self.node .clone() - .node_on_button(seat, button, state, serial); + .node_on_button(seat, time_usec, button, state, serial); } fn axis_node(&self, _seat: &Rc) -> Option> { @@ -400,7 +401,7 @@ impl PointerOwner for GrabPointerOwner { } impl PointerOwner for DndPointerOwner { - fn button(&self, seat: &Rc, button: u32, state: KeyState) { + fn button(&self, seat: &Rc, _time_usec: u64, button: u32, state: KeyState) { if button != self.button || state != KeyState::Released { return; } @@ -468,7 +469,7 @@ impl PointerOwner for DndPointerOwner { target.node_seat_state().add_dnd_target(seat); self.target.set(target); } else if (self.pos_x.get(), self.pos_y.get()) != (x, y) { - node.node_on_dnd_motion(&self.dnd, x, y); + node.node_on_dnd_motion(&self.dnd, seat.pos_time_usec.get(), x, y); } self.pos_x.set(x); self.pos_y.set(y); diff --git a/src/ifs/wl_seat/wl_pointer.rs b/src/ifs/wl_seat/wl_pointer.rs index 2ff0bd91..28b5de79 100644 --- a/src/ifs/wl_seat/wl_pointer.rs +++ b/src/ifs/wl_seat/wl_pointer.rs @@ -40,6 +40,7 @@ pub struct PendingScroll { pub axis: [Cell>; 2], pub stop: [Cell; 2], pub source: Cell>, + pub time_usec: Cell, } impl PendingScroll { @@ -58,6 +59,7 @@ impl PendingScroll { Cell::new(self.stop[1].take()), ], source: Cell::new(self.source.take()), + time_usec: Cell::new(self.time_usec.take()), } } } diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 19479333..8b884caf 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -760,8 +760,8 @@ impl Node for WlSurface { self.toplevel.get() } - fn node_on_key(&self, seat: &WlSeatGlobal, key: u32, state: u32) { - seat.key_surface(self, key, state); + fn node_on_key(&self, seat: &WlSeatGlobal, time_usec: u64, key: u32, state: u32) { + seat.key_surface(self, time_usec, key, state); } fn node_on_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) { @@ -771,11 +771,12 @@ impl Node for WlSurface { fn node_on_button( self: Rc, seat: &Rc, + time_usec: u64, button: u32, state: KeyState, serial: u32, ) { - seat.button_surface(&self, button, state, serial); + seat.button_surface(&self, time_usec, button, state, serial); } fn node_on_axis_event(self: Rc, seat: &Rc, event: &PendingScroll) { @@ -830,8 +831,8 @@ impl Node for WlSurface { dnd.seat.dnd_surface_enter(self, dnd, x, y, serial); } - fn node_on_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) { - dnd.seat.dnd_surface_motion(self, dnd, x, y); + fn node_on_dnd_motion(&self, dnd: &Dnd, time_usec: u64, x: Fixed, y: Fixed) { + dnd.seat.dnd_surface_motion(self, dnd, time_usec, x, y); } fn node_into_surface(self: Rc) -> Option> { diff --git a/src/it/test_backend.rs b/src/it/test_backend.rs index 35b3ba7d..62c9a823 100644 --- a/src/it/test_backend.rs +++ b/src/it/test_backend.rs @@ -12,7 +12,7 @@ use { it::test_error::TestResult, render::{RenderContext, RenderError}, state::State, - time::Time, + time::now_usec, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, oserror::OsError, syncqueue::SyncQueue, }, @@ -255,9 +255,11 @@ pub struct TestMouseClick { impl Drop for TestMouseClick { fn drop(&mut self) { - self.mouse - .common - .event(InputEvent::Button(self.button, KeyState::Released)); + self.mouse.common.event(InputEvent::Button { + time_usec: now_usec(), + button: self.button, + state: KeyState::Released, + }); } } @@ -272,7 +274,7 @@ pub struct TestBackendMouse { impl TestBackendMouse { pub fn rel(&self, dx: f64, dy: f64) { self.common.event(InputEvent::Motion { - time_usec: Time::now_unchecked().usec(), + time_usec: now_usec(), dx: Fixed::from_f64(dx * self.accel_speed.get()), dy: Fixed::from_f64(dy * self.accel_speed.get()), dx_unaccelerated: Fixed::from_f64(dx), @@ -282,15 +284,19 @@ impl TestBackendMouse { pub fn abs(&self, connector: &TestConnector, x: f64, y: f64) { self.common.event(InputEvent::ConnectorPosition { - 0: connector.id, - 1: Fixed::from_f64(x), - 2: Fixed::from_f64(y), + time_usec: now_usec(), + connector: connector.id, + x: Fixed::from_f64(x), + y: Fixed::from_f64(y), }) } pub fn click(self: &Rc, button: u32) -> TestMouseClick { - self.common - .event(InputEvent::Button(button, KeyState::Pressed)); + self.common.event(InputEvent::Button { + time_usec: now_usec(), + button, + state: KeyState::Pressed, + }); TestMouseClick { mouse: self.clone(), button, @@ -298,21 +304,33 @@ impl TestBackendMouse { } pub fn scroll(&self, dy: i32) { - self.common.event(InputEvent::AxisSource(AxisSource::Wheel)); - self.common - .event(InputEvent::AxisDiscrete(dy, ScrollAxis::Vertical)); - self.common.event(InputEvent::Axis( - Fixed::from_int(dy * 15), - ScrollAxis::Vertical, - )); - self.common.event(InputEvent::Frame); + self.common.event(InputEvent::AxisSource { + source: AxisSource::Wheel, + }); + self.common.event(InputEvent::AxisDiscrete { + dist: dy, + axis: ScrollAxis::Vertical, + }); + self.common.event(InputEvent::Axis { + dist: Fixed::from_int(dy * 15), + axis: ScrollAxis::Vertical, + }); + self.common.event(InputEvent::AxisFrame { + time_usec: now_usec(), + }); } pub fn scroll_px(&self, dy: i32) { - self.common.event(InputEvent::AxisSource(AxisSource::Wheel)); - self.common - .event(InputEvent::Axis(Fixed::from_int(dy), ScrollAxis::Vertical)); - self.common.event(InputEvent::Frame); + self.common.event(InputEvent::AxisSource { + source: AxisSource::Wheel, + }); + self.common.event(InputEvent::Axis { + dist: Fixed::from_int(dy), + axis: ScrollAxis::Vertical, + }); + self.common.event(InputEvent::AxisFrame { + time_usec: now_usec(), + }); } } @@ -327,15 +345,21 @@ pub struct PressedKey { impl Drop for PressedKey { fn drop(&mut self) { - self.kb - .common - .event(InputEvent::Key(self.key, KeyState::Released)); + self.kb.common.event(InputEvent::Key { + time_usec: now_usec(), + key: self.key, + state: KeyState::Released, + }); } } impl TestBackendKb { pub fn press(self: &Rc, key: u32) -> PressedKey { - self.common.event(InputEvent::Key(key, KeyState::Pressed)); + self.common.event(InputEvent::Key { + time_usec: now_usec(), + key, + state: KeyState::Pressed, + }); PressedKey { kb: self.clone(), key, diff --git a/src/time.rs b/src/time.rs index 7b34d9fa..c4da837d 100644 --- a/src/time.rs +++ b/src/time.rs @@ -118,3 +118,7 @@ impl Add for Time { self } } + +pub fn now_usec() -> u64 { + Time::now_unchecked().usec() +} diff --git a/src/tree.rs b/src/tree.rs index de492ce7..6e31beb6 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -157,8 +157,9 @@ pub trait Node: 'static { // EVENT HANDLERS - fn node_on_key(&self, seat: &WlSeatGlobal, key: u32, state: u32) { + fn node_on_key(&self, seat: &WlSeatGlobal, time_usec: u64, key: u32, state: u32) { let _ = seat; + let _ = time_usec; let _ = key; let _ = state; } @@ -171,11 +172,13 @@ pub trait Node: 'static { fn node_on_button( self: Rc, seat: &Rc, + time_usec: u64, button: u32, state: KeyState, serial: u32, ) { let _ = seat; + let _ = time_usec; let _ = button; let _ = state; let _ = serial; @@ -251,8 +254,9 @@ pub trait Node: 'static { let _ = serial; } - fn node_on_dnd_motion(&self, dnd: &Dnd, x: Fixed, y: Fixed) { + fn node_on_dnd_motion(&self, dnd: &Dnd, time_usec: u64, x: Fixed, y: Fixed) { let _ = dnd; + let _ = time_usec; let _ = x; let _ = y; } diff --git a/src/tree/container.rs b/src/tree/container.rs index 17debdec..957c067e 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -1079,6 +1079,7 @@ impl Node for ContainerNode { fn node_on_button( self: Rc, seat: &Rc, + _time_usec: u64, button: u32, state: KeyState, _serial: u32, diff --git a/src/tree/float.rs b/src/tree/float.rs index 54924223..c439c97c 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -406,6 +406,7 @@ impl Node for FloatNode { fn node_on_button( self: Rc, seat: &Rc, + _time_usec: u64, button: u32, state: KeyState, _serial: u32, diff --git a/src/tree/output.rs b/src/tree/output.rs index 9fe510bc..de93a59c 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -483,6 +483,7 @@ impl Node for OutputNode { fn node_on_button( self: Rc, seat: &Rc, + _time_usec: u64, button: u32, state: KeyState, _serial: u32,