1
0
Fork 0
forked from wry/wry

wayland: add times to all input events

This commit is contained in:
Julian Orth 2022-05-26 12:25:59 +02:00
parent 568341a3d0
commit 145e4dbc24
16 changed files with 235 additions and 101 deletions

View file

@ -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 {

View file

@ -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,
});
}
}
}

View file

@ -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<Self>, 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<Self>, 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<Self>, event: LibInputEvent) {

View file

@ -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(())
}

View file

@ -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,
})

View file

@ -116,6 +116,7 @@ pub struct WlSeatGlobal {
move_: Cell<bool>,
move_start_pos: Cell<(Fixed, Fixed)>,
extents_start_pos: Cell<(i32, i32)>,
pos_time_usec: Cell<u64>,
pos: Cell<(Fixed, Fixed)>,
pointer_stack: RefCell<Vec<Rc<dyn Node>>>,
pointer_stack_modified: Cell<bool>,
@ -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),

View file

@ -167,8 +167,17 @@ impl NodeSeatState {
impl WlSeatGlobal {
pub fn event(self: &Rc<Self>, 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<Self>,
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<Self>, x: Fixed, y: Fixed) {
fn set_new_position(self: &Rc<Self>, 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<Self>,
surface: &Rc<WlSurface>,
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();

View file

@ -31,8 +31,8 @@ impl Default for PointerOwnerHolder {
}
impl PointerOwnerHolder {
pub fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
self.owner.get().button(seat, button, state)
pub fn button(&self, seat: &Rc<WlSeatGlobal>, 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<WlSeatGlobal>) {
pub fn frame(&self, seat: &Rc<WlSeatGlobal>, 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<WlSeatGlobal>, button: u32, state: KeyState);
fn button(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, button: u32, state: KeyState);
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>>;
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>);
fn start_drag(
@ -158,7 +159,7 @@ struct DndPointerOwner {
}
impl PointerOwner for DefaultPointerOwner {
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
fn button(&self, seat: &Rc<WlSeatGlobal>, 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<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
@ -280,7 +281,7 @@ impl PointerOwner for DefaultPointerOwner {
}
impl PointerOwner for GrabPointerOwner {
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
fn button(&self, seat: &Rc<WlSeatGlobal>, 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<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
@ -400,7 +401,7 @@ impl PointerOwner for GrabPointerOwner {
}
impl PointerOwner for DndPointerOwner {
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
fn button(&self, seat: &Rc<WlSeatGlobal>, _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);

View file

@ -40,6 +40,7 @@ pub struct PendingScroll {
pub axis: [Cell<Option<Fixed>>; 2],
pub stop: [Cell<bool>; 2],
pub source: Cell<Option<u32>>,
pub time_usec: Cell<u64>,
}
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()),
}
}
}

View file

@ -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<Self>,
seat: &Rc<WlSeatGlobal>,
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<Self>, seat: &Rc<WlSeatGlobal>, 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<Self>) -> Option<Rc<WlSurface>> {

View file

@ -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<Self>, 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<Self>, 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,

View file

@ -118,3 +118,7 @@ impl Add<Duration> for Time {
self
}
}
pub fn now_usec() -> u64 {
Time::now_unchecked().usec()
}

View file

@ -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<Self>,
seat: &Rc<WlSeatGlobal>,
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;
}

View file

@ -1079,6 +1079,7 @@ impl Node for ContainerNode {
fn node_on_button(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,
_time_usec: u64,
button: u32,
state: KeyState,
_serial: u32,

View file

@ -406,6 +406,7 @@ impl Node for FloatNode {
fn node_on_button(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,
_time_usec: u64,
button: u32,
state: KeyState,
_serial: u32,

View file

@ -483,6 +483,7 @@ impl Node for OutputNode {
fn node_on_button(
self: Rc<Self>,
seat: &Rc<WlSeatGlobal>,
_time_usec: u64,
button: u32,
state: KeyState,
_serial: u32,