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)] #[derive(Debug)]
pub enum InputEvent { pub enum InputEvent {
Key(u32, KeyState), Key {
ConnectorPosition(ConnectorId, Fixed, Fixed), time_usec: u64,
key: u32,
state: KeyState,
},
ConnectorPosition {
time_usec: u64,
connector: ConnectorId,
x: Fixed,
y: Fixed,
},
Motion { Motion {
time_usec: u64, time_usec: u64,
dx: Fixed, dx: Fixed,
@ -159,13 +168,29 @@ pub enum InputEvent {
dx_unaccelerated: Fixed, dx_unaccelerated: Fixed,
dy_unaccelerated: Fixed, dy_unaccelerated: Fixed,
}, },
Button(u32, KeyState), Button {
time_usec: u64,
button: u32,
state: KeyState,
},
Axis(Fixed, ScrollAxis), Axis {
AxisSource(AxisSource), dist: Fixed,
AxisStop(ScrollAxis), axis: ScrollAxis,
AxisDiscrete(i32, ScrollAxis), },
Frame, AxisSource {
source: AxisSource,
},
AxisStop {
axis: ScrollAxis,
},
AxisDiscrete {
dist: i32,
axis: ScrollAxis,
},
AxisFrame {
time_usec: u64,
},
} }
pub enum DrmEvent { pub enum DrmEvent {

View file

@ -25,6 +25,7 @@ use {
logind::{LogindError, Session}, logind::{LogindError, Session},
render::RenderError, render::RenderError,
state::State, state::State,
time::now_usec,
udev::{Udev, UdevError, UdevMonitor}, udev::{Udev, UdevError, UdevMonitor},
utils::{ utils::{
clonecell::{CloneCell, UnsafeCellCloneSafe}, clonecell::{CloneCell, UnsafeCellCloneSafe},
@ -341,11 +342,20 @@ impl MetalInputDevice {
} }
fn pre_pause(&self) { fn pre_pause(&self) {
let time_usec = now_usec();
for (key, _) in self.pressed_keys.take() { 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() { 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 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) { fn handle_pointer_axis(self: &Rc<Self>, event: LibInputEvent, source: AxisSource) {
@ -132,7 +136,7 @@ impl MetalBackend {
), ),
(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical), (LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical),
]; ];
dev.event(InputEvent::AxisSource(source)); dev.event(InputEvent::AxisSource { source });
for (axis, sa) in axes { for (axis, sa) in axes {
if !event.has_axis(axis) { if !event.has_axis(axis) {
continue; continue;
@ -142,17 +146,25 @@ impl MetalBackend {
_ => event.scroll_value(axis), _ => event.scroll_value(axis),
}; };
if scroll == 0.0 { if scroll == 0.0 {
dev.event(InputEvent::AxisStop(sa)); dev.event(InputEvent::AxisStop { axis: sa });
} else { } else {
if source == AxisSource::Wheel { if source == AxisSource::Wheel {
let scroll_discrete = scroll / ONE_TWENTRY; 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; 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) { fn handle_pointer_button(self: &Rc<Self>, event: LibInputEvent) {
@ -168,7 +180,11 @@ impl MetalBackend {
} }
KeyState::Released 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) { fn handle_pointer_motion(self: &Rc<Self>, event: LibInputEvent) {

View file

@ -12,6 +12,7 @@ use {
ifs::wl_seat::PX_PER_SCROLL, ifs::wl_seat::PX_PER_SCROLL,
render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture}, render::{Framebuffer, RenderContext, RenderError, RenderResult, Texture},
state::State, state::State,
time::now_usec,
utils::{ utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
queue::AsyncQueue, syncqueue::SyncQueue, queue::AsyncQueue, syncqueue::SyncQueue,
@ -761,13 +762,17 @@ impl XBackend {
7 => (ScrollAxis::Horizontal, 1), 7 => (ScrollAxis::Horizontal, 1),
_ => unreachable!(), _ => unreachable!(),
}; };
seat.mouse_event(InputEvent::AxisSource(AxisSource::Wheel)); seat.mouse_event(InputEvent::AxisSource {
seat.mouse_event(InputEvent::AxisDiscrete(val, axis)); source: AxisSource::Wheel,
seat.mouse_event(InputEvent::Axis( });
Fixed::from_f64(val as f64 * PX_PER_SCROLL), seat.mouse_event(InputEvent::AxisDiscrete { dist: val, axis });
seat.mouse_event(InputEvent::Axis {
dist: Fixed::from_f64(val as f64 * PX_PER_SCROLL),
axis, axis,
)); });
seat.mouse_event(InputEvent::Frame); seat.mouse_event(InputEvent::AxisFrame {
time_usec: now_usec(),
});
} }
} else { } else {
const BTN_LEFT: u32 = 0x110; const BTN_LEFT: u32 = 0x110;
@ -781,7 +786,11 @@ impl XBackend {
3 => BTN_RIGHT, 3 => BTN_RIGHT,
n => BTN_SIDE + n - 8, n => BTN_SIDE + n - 8,
}; };
seat.mouse_event(InputEvent::Button(button, state)); seat.mouse_event(InputEvent::Button {
time_usec: now_usec(),
button,
state,
});
} }
} }
Ok(()) Ok(())
@ -794,7 +803,11 @@ impl XBackend {
) -> Result<(), XBackendError> { ) -> Result<(), XBackendError> {
let event: XiKeyPress = event.parse()?; let event: XiKeyPress = event.parse()?;
if let Some(seat) = self.seats.get(&event.deviceid) { 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(()) Ok(())
} }
@ -824,11 +837,12 @@ impl XBackend {
self.outputs.get(&event.event), self.outputs.get(&event.event),
self.mouse_seats.get(&event.deviceid), self.mouse_seats.get(&event.deviceid),
) { ) {
seat.mouse_event(InputEvent::ConnectorPosition( seat.mouse_event(InputEvent::ConnectorPosition {
win.id, time_usec: now_usec(),
Fixed::from_1616(event.event_x), connector: win.id,
Fixed::from_1616(event.event_y), x: Fixed::from_1616(event.event_x),
)); y: Fixed::from_1616(event.event_y),
});
} }
Ok(()) Ok(())
} }
@ -842,11 +856,12 @@ impl XBackend {
(Some(a), Some(b)) => (a, b), (Some(a), Some(b)) => (a, b),
_ => return Ok(()), _ => return Ok(()),
}; };
seat.mouse_event(InputEvent::ConnectorPosition( seat.mouse_event(InputEvent::ConnectorPosition {
win.id, time_usec: now_usec(),
Fixed::from_1616(event.event_x), connector: win.id,
Fixed::from_1616(event.event_y), x: Fixed::from_1616(event.event_x),
)); y: Fixed::from_1616(event.event_y),
});
Ok(()) 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 { if !self.data.is_xwm {
self.client.event(Motion { self.client.event(Motion {
self_id: self.id, self_id: self.id,
time: 0, time: (time_usec / 1000) as _,
x, x,
y, y,
}) })

View file

@ -116,6 +116,7 @@ pub struct WlSeatGlobal {
move_: Cell<bool>, move_: Cell<bool>,
move_start_pos: Cell<(Fixed, Fixed)>, move_start_pos: Cell<(Fixed, Fixed)>,
extents_start_pos: Cell<(i32, i32)>, extents_start_pos: Cell<(i32, i32)>,
pos_time_usec: Cell<u64>,
pos: Cell<(Fixed, Fixed)>, pos: Cell<(Fixed, Fixed)>,
pointer_stack: RefCell<Vec<Rc<dyn Node>>>, pointer_stack: RefCell<Vec<Rc<dyn Node>>>,
pointer_stack_modified: Cell<bool>, pointer_stack_modified: Cell<bool>,
@ -163,6 +164,7 @@ impl WlSeatGlobal {
move_: Cell::new(false), move_: Cell::new(false),
move_start_pos: Cell::new((Fixed(0), Fixed(0))), move_start_pos: Cell::new((Fixed(0), Fixed(0))),
extents_start_pos: Cell::new((0, 0)), extents_start_pos: Cell::new((0, 0)),
pos_time_usec: Cell::new(0),
pos: Cell::new((Fixed(0), Fixed(0))), pos: Cell::new((Fixed(0), Fixed(0))),
pointer_stack: RefCell::new(vec![]), pointer_stack: RefCell::new(vec![]),
pointer_stack_modified: Cell::new(false), pointer_stack_modified: Cell::new(false),

View file

@ -167,8 +167,17 @@ impl NodeSeatState {
impl WlSeatGlobal { impl WlSeatGlobal {
pub fn event(self: &Rc<Self>, event: InputEvent) { pub fn event(self: &Rc<Self>, event: InputEvent) {
match event { match event {
InputEvent::Key(k, s) => self.key_event(k, s), InputEvent::Key {
InputEvent::ConnectorPosition(o, x, y) => self.connector_position_event(o, x, y), 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 { InputEvent::Motion {
dx, dx,
dy, dy,
@ -176,18 +185,23 @@ impl WlSeatGlobal {
dy_unaccelerated, dy_unaccelerated,
time_usec, time_usec,
} => self.motion_event(time_usec, dx, dy, dx_unaccelerated, dy_unaccelerated), } => 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::AxisSource { source } => self.pointer_owner.axis_source(source),
InputEvent::AxisDiscrete(d, a) => self.pointer_owner.axis_discrete(d, a), InputEvent::AxisDiscrete { dist, axis } => self.pointer_owner.axis_discrete(dist, axis),
InputEvent::Axis(d, a) => self.pointer_owner.axis(d, a), InputEvent::Axis { dist, axis } => self.pointer_owner.axis(dist, axis),
InputEvent::AxisStop(d) => self.pointer_owner.axis_stop(d), InputEvent::AxisStop { axis } => self.pointer_owner.axis_stop(axis),
InputEvent::Frame => self.pointer_owner.frame(self), InputEvent::AxisFrame { time_usec } => self.pointer_owner.frame(self, time_usec),
} }
} }
fn connector_position_event( fn connector_position_event(
self: &Rc<Self>, self: &Rc<Self>,
time_usec: u64,
connector: ConnectorId, connector: ConnectorId,
mut x: Fixed, mut x: Fixed,
mut y: Fixed, mut y: Fixed,
@ -200,7 +214,7 @@ impl WlSeatGlobal {
let pos = output.node.global.pos.get(); let pos = output.node.global.pos.get();
x += Fixed::from_int(pos.x1()); x += Fixed::from_int(pos.x1());
y += Fixed::from_int(pos.y1()); y += Fixed::from_int(pos.y1());
self.set_new_position(x, y); self.set_new_position(time_usec, x, y);
} }
fn motion_event( fn motion_event(
@ -249,10 +263,10 @@ impl WlSeatGlobal {
y = y.apply_fract(y_int); 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 (state, xkb_dir) = {
let mut pk = self.pressed_keys.borrow_mut(); let mut pk = self.pressed_keys.borrow_mut();
match state { match state {
@ -290,7 +304,7 @@ impl WlSeatGlobal {
} }
let node = self.keyboard_node.get(); let node = self.keyboard_node.get();
if shortcuts.is_empty() { 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() { } else if let Some(config) = self.state.config.get() {
for shortcut in shortcuts { for shortcut in shortcuts {
config.invoke_shortcut(self.id(), &shortcut); config.invoke_shortcut(self.id(), &shortcut);
@ -461,7 +475,8 @@ impl WlSeatGlobal {
// client.flush(); // 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)); self.pos.set((x, y));
if let Some(cursor) = self.cursor.get() { if let Some(cursor) = self.cursor.get() {
cursor.set_position(x.round_down(), y.round_down()); cursor.set_position(x.round_down(), y.round_down());
@ -499,6 +514,7 @@ impl WlSeatGlobal {
pub fn button_surface( pub fn button_surface(
self: &Rc<Self>, self: &Rc<Self>,
surface: &Rc<WlSurface>, surface: &Rc<WlSurface>,
time_usec: u64,
button: u32, button: u32,
state: KeyState, state: KeyState,
serial: u32, serial: u32,
@ -507,7 +523,8 @@ impl WlSeatGlobal {
KeyState::Released => (wl_pointer::RELEASED, false), KeyState::Released => (wl_pointer::RELEASED, false),
KeyState::Pressed => (wl_pointer::PRESSED, true), 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); self.surface_pointer_frame(surface);
if pressed { if pressed {
if let Some(node) = surface.get_focus_node(self.id) { 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)); 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 { for i in 0..1 {
if let Some(delta) = event.discrete[i].get() { if let Some(delta) = event.discrete[i].get() {
self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| { self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| {
@ -535,11 +553,11 @@ impl WlSeatGlobal {
}); });
} }
if let Some(delta) = event.axis[i].get() { 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() { if event.stop[i].get() {
self.surface_pointer_event(AXIS_STOP_SINCE_VERSION, surface, |p| { 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 // Motion callbacks
impl WlSeatGlobal { impl WlSeatGlobal {
pub fn motion_surface(&self, n: &WlSurface, x: Fixed, y: Fixed) { 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); self.surface_pointer_frame(n);
} }
} }
@ -638,9 +657,10 @@ impl WlSeatGlobal {
// Key callbacks // Key callbacks
impl WlSeatGlobal { 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(); 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(); // 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 { if dnd.src.is_some() || surface.client.id == dnd.client.id {
self.for_each_data_device(0, surface.client.id, |dd| { 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(); // surface.client.flush();

View file

@ -31,8 +31,8 @@ impl Default for PointerOwnerHolder {
} }
impl PointerOwnerHolder { impl PointerOwnerHolder {
pub fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) { pub fn button(&self, seat: &Rc<WlSeatGlobal>, time_usec: u64, button: u32, state: KeyState) {
self.owner.get().button(seat, button, state) self.owner.get().button(seat, time_usec, button, state)
} }
pub fn axis_source(&self, axis_source: AxisSource) { pub fn axis_source(&self, axis_source: AxisSource) {
@ -51,7 +51,8 @@ impl PointerOwnerHolder {
self.pending_scroll.stop[axis as usize].set(true); 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(); let pending = self.pending_scroll.take();
if let Some(node) = self.owner.get().axis_node(seat) { if let Some(node) = self.owner.get().axis_node(seat) {
node.node_on_axis_event(seat, &pending); node.node_on_axis_event(seat, &pending);
@ -122,7 +123,7 @@ impl PointerOwnerHolder {
} }
trait PointerOwner { 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 axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>>;
fn apply_changes(&self, seat: &Rc<WlSeatGlobal>); fn apply_changes(&self, seat: &Rc<WlSeatGlobal>);
fn start_drag( fn start_drag(
@ -158,7 +159,7 @@ struct DndPointerOwner {
} }
impl PointerOwner for DefaultPointerOwner { 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 { if state != KeyState::Pressed {
return; return;
} }
@ -173,7 +174,7 @@ impl PointerOwner for DefaultPointerOwner {
serial, serial,
})); }));
pn.node_seat_state().add_pointer_grab(seat); 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>> { fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
@ -280,7 +281,7 @@ impl PointerOwner for DefaultPointerOwner {
} }
impl PointerOwner for GrabPointerOwner { 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 { match state {
KeyState::Released => { KeyState::Released => {
self.buttons.remove(&button); self.buttons.remove(&button);
@ -300,7 +301,7 @@ impl PointerOwner for GrabPointerOwner {
let serial = seat.state.next_serial(self.node.node_client().as_deref()); let serial = seat.state.next_serial(self.node.node_client().as_deref());
self.node self.node
.clone() .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>> { fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
@ -400,7 +401,7 @@ impl PointerOwner for GrabPointerOwner {
} }
impl PointerOwner for DndPointerOwner { 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 { if button != self.button || state != KeyState::Released {
return; return;
} }
@ -468,7 +469,7 @@ impl PointerOwner for DndPointerOwner {
target.node_seat_state().add_dnd_target(seat); target.node_seat_state().add_dnd_target(seat);
self.target.set(target); self.target.set(target);
} else if (self.pos_x.get(), self.pos_y.get()) != (x, y) { } 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_x.set(x);
self.pos_y.set(y); self.pos_y.set(y);

View file

@ -40,6 +40,7 @@ pub struct PendingScroll {
pub axis: [Cell<Option<Fixed>>; 2], pub axis: [Cell<Option<Fixed>>; 2],
pub stop: [Cell<bool>; 2], pub stop: [Cell<bool>; 2],
pub source: Cell<Option<u32>>, pub source: Cell<Option<u32>>,
pub time_usec: Cell<u64>,
} }
impl PendingScroll { impl PendingScroll {
@ -58,6 +59,7 @@ impl PendingScroll {
Cell::new(self.stop[1].take()), Cell::new(self.stop[1].take()),
], ],
source: Cell::new(self.source.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() self.toplevel.get()
} }
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) {
seat.key_surface(self, key, state); seat.key_surface(self, time_usec, key, state);
} }
fn node_on_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) { fn node_on_mods(&self, seat: &WlSeatGlobal, mods: ModifierState) {
@ -771,11 +771,12 @@ impl Node for WlSurface {
fn node_on_button( fn node_on_button(
self: Rc<Self>, self: Rc<Self>,
seat: &Rc<WlSeatGlobal>, seat: &Rc<WlSeatGlobal>,
time_usec: u64,
button: u32, button: u32,
state: KeyState, state: KeyState,
serial: u32, 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) { 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); dnd.seat.dnd_surface_enter(self, dnd, x, y, 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) {
dnd.seat.dnd_surface_motion(self, dnd, x, y); dnd.seat.dnd_surface_motion(self, dnd, time_usec, x, y);
} }
fn node_into_surface(self: Rc<Self>) -> Option<Rc<WlSurface>> { fn node_into_surface(self: Rc<Self>) -> Option<Rc<WlSurface>> {

View file

@ -12,7 +12,7 @@ use {
it::test_error::TestResult, it::test_error::TestResult,
render::{RenderContext, RenderError}, render::{RenderContext, RenderError},
state::State, state::State,
time::Time, time::now_usec,
utils::{ utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, oserror::OsError, syncqueue::SyncQueue, clonecell::CloneCell, copyhashmap::CopyHashMap, oserror::OsError, syncqueue::SyncQueue,
}, },
@ -255,9 +255,11 @@ pub struct TestMouseClick {
impl Drop for TestMouseClick { impl Drop for TestMouseClick {
fn drop(&mut self) { fn drop(&mut self) {
self.mouse self.mouse.common.event(InputEvent::Button {
.common time_usec: now_usec(),
.event(InputEvent::Button(self.button, KeyState::Released)); button: self.button,
state: KeyState::Released,
});
} }
} }
@ -272,7 +274,7 @@ pub struct TestBackendMouse {
impl TestBackendMouse { impl TestBackendMouse {
pub fn rel(&self, dx: f64, dy: f64) { pub fn rel(&self, dx: f64, dy: f64) {
self.common.event(InputEvent::Motion { self.common.event(InputEvent::Motion {
time_usec: Time::now_unchecked().usec(), time_usec: now_usec(),
dx: Fixed::from_f64(dx * self.accel_speed.get()), dx: Fixed::from_f64(dx * self.accel_speed.get()),
dy: Fixed::from_f64(dy * self.accel_speed.get()), dy: Fixed::from_f64(dy * self.accel_speed.get()),
dx_unaccelerated: Fixed::from_f64(dx), dx_unaccelerated: Fixed::from_f64(dx),
@ -282,15 +284,19 @@ impl TestBackendMouse {
pub fn abs(&self, connector: &TestConnector, x: f64, y: f64) { pub fn abs(&self, connector: &TestConnector, x: f64, y: f64) {
self.common.event(InputEvent::ConnectorPosition { self.common.event(InputEvent::ConnectorPosition {
0: connector.id, time_usec: now_usec(),
1: Fixed::from_f64(x), connector: connector.id,
2: Fixed::from_f64(y), x: Fixed::from_f64(x),
y: Fixed::from_f64(y),
}) })
} }
pub fn click(self: &Rc<Self>, button: u32) -> TestMouseClick { pub fn click(self: &Rc<Self>, button: u32) -> TestMouseClick {
self.common self.common.event(InputEvent::Button {
.event(InputEvent::Button(button, KeyState::Pressed)); time_usec: now_usec(),
button,
state: KeyState::Pressed,
});
TestMouseClick { TestMouseClick {
mouse: self.clone(), mouse: self.clone(),
button, button,
@ -298,21 +304,33 @@ impl TestBackendMouse {
} }
pub fn scroll(&self, dy: i32) { pub fn scroll(&self, dy: i32) {
self.common.event(InputEvent::AxisSource(AxisSource::Wheel)); self.common.event(InputEvent::AxisSource {
self.common source: AxisSource::Wheel,
.event(InputEvent::AxisDiscrete(dy, ScrollAxis::Vertical)); });
self.common.event(InputEvent::Axis( self.common.event(InputEvent::AxisDiscrete {
Fixed::from_int(dy * 15), dist: dy,
ScrollAxis::Vertical, axis: ScrollAxis::Vertical,
)); });
self.common.event(InputEvent::Frame); 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) { pub fn scroll_px(&self, dy: i32) {
self.common.event(InputEvent::AxisSource(AxisSource::Wheel)); self.common.event(InputEvent::AxisSource {
self.common source: AxisSource::Wheel,
.event(InputEvent::Axis(Fixed::from_int(dy), ScrollAxis::Vertical)); });
self.common.event(InputEvent::Frame); 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 { impl Drop for PressedKey {
fn drop(&mut self) { fn drop(&mut self) {
self.kb self.kb.common.event(InputEvent::Key {
.common time_usec: now_usec(),
.event(InputEvent::Key(self.key, KeyState::Released)); key: self.key,
state: KeyState::Released,
});
} }
} }
impl TestBackendKb { impl TestBackendKb {
pub fn press(self: &Rc<Self>, key: u32) -> PressedKey { 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 { PressedKey {
kb: self.clone(), kb: self.clone(),
key, key,

View file

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

View file

@ -157,8 +157,9 @@ pub trait Node: 'static {
// EVENT HANDLERS // 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 _ = seat;
let _ = time_usec;
let _ = key; let _ = key;
let _ = state; let _ = state;
} }
@ -171,11 +172,13 @@ pub trait Node: 'static {
fn node_on_button( fn node_on_button(
self: Rc<Self>, self: Rc<Self>,
seat: &Rc<WlSeatGlobal>, seat: &Rc<WlSeatGlobal>,
time_usec: u64,
button: u32, button: u32,
state: KeyState, state: KeyState,
serial: u32, serial: u32,
) { ) {
let _ = seat; let _ = seat;
let _ = time_usec;
let _ = button; let _ = button;
let _ = state; let _ = state;
let _ = serial; let _ = serial;
@ -251,8 +254,9 @@ pub trait Node: 'static {
let _ = serial; 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 _ = dnd;
let _ = time_usec;
let _ = x; let _ = x;
let _ = y; let _ = y;
} }

View file

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

View file

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

View file

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