From 00aa689e7a4365155c1922d6ca998c45f35d2bf6 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Thu, 29 May 2025 00:01:31 +0200 Subject: [PATCH] pointer-constraints: defer cursor position update --- src/ei/ei_ifs/ei_device.rs | 2 +- src/ifs/wl_seat.rs | 2 +- src/ifs/wl_seat/event_handling.rs | 20 +++++++++++-------- src/ifs/wl_seat/zwp_pointer_constraints_v1.rs | 9 +++++---- src/ifs/wl_surface.rs | 2 +- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/ei/ei_ifs/ei_device.rs b/src/ei/ei_ifs/ei_device.rs index a9b2e39c..e7a4cba0 100644 --- a/src/ei/ei_ifs/ei_device.rs +++ b/src/ei/ei_ifs/ei_device.rs @@ -201,7 +201,7 @@ impl EiDeviceRequestHandler for EiDevice { if let Some((x, y)) = self.absolute_motion.take() { let x = Fixed::from_f32(x); let y = Fixed::from_f32(y); - seat.motion_event_abs(time, x, y); + seat.motion_event_abs(time, x, y, false); } { let mut need_frame = false; diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 9ebf00e1..7de5a81a 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -432,7 +432,7 @@ impl WlSeatGlobal { pub fn disable_pointer_constraint(&self) { if let Some(constraint) = self.constraint.get() { - constraint.deactivate(true); + constraint.deactivate(true, true); if constraint.status.get() == SeatConstraintStatus::Inactive { constraint .status diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index 91d5eec5..02b02f6b 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -516,23 +516,23 @@ impl WlSeatGlobal { let pos = output.global.pos.get(); x += Fixed::from_int(pos.x1()); y += Fixed::from_int(pos.y1()); - self.motion_event_abs(time_usec, x, y); + self.motion_event_abs(time_usec, x, y, false); } - pub fn motion_event_abs(self: &Rc, time_usec: u64, x: Fixed, y: Fixed) { + pub fn motion_event_abs(self: &Rc, time_usec: u64, x: Fixed, y: Fixed, defer: bool) { self.for_each_ei_seat(|ei_seat| { ei_seat.handle_motion_abs(time_usec, x, y); }); let (x, y) = self.set_pointer_cursor_position(x, y); if let Some(c) = self.constraint.get() { if c.ty == ConstraintType::Lock || !c.contains(x.round_down(), y.round_down()) { - c.deactivate(false); + c.deactivate(false, false); } } self.state.for_each_seat_tester(|t| { t.send_pointer_abs(self.id, time_usec, x, y); }); - self.cursor_moved(time_usec); + self.cursor_moved(time_usec, defer); } pub fn motion_event( @@ -587,7 +587,7 @@ impl WlSeatGlobal { ); }); self.set_pointer_cursor_position(x, y); - self.cursor_moved(time_usec); + self.cursor_moved(time_usec, false); } pub fn button_event(self: &Rc, time_usec: u64, button: u32, state: KeyState) { @@ -1095,10 +1095,14 @@ impl WlSeatGlobal { }); } - fn cursor_moved(self: &Rc, time_usec: u64) { + fn cursor_moved(self: &Rc, time_usec: u64, defer: bool) { self.pos_time_usec.set(time_usec); self.changes.or_assign(CHANGE_CURSOR_MOVED); - self.apply_changes(); + if defer { + self.trigger_tree_changed(false); + } else { + self.apply_changes(); + } } pub fn emulate_cursor_moved(&self) { @@ -1285,7 +1289,7 @@ impl WlSeatGlobal { pub fn leave_surface(&self, n: &WlSurface) { let serial = n.client.next_serial(); for (_, constraint) in &n.constraints { - constraint.deactivate(true); + constraint.deactivate(true, true); } self.surface_pointer_event(Version::ALL, n, |p| p.send_leave(serial, n.id)); self.surface_pointer_frame(n); diff --git a/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs b/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs index 19051d79..b58e5412 100644 --- a/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs +++ b/src/ifs/wl_seat/zwp_pointer_constraints_v1.rs @@ -65,10 +65,10 @@ pub struct SeatConstraint { } impl SeatConstraint { - pub fn deactivate(&self, apply_position_hint: bool) { + pub fn deactivate(&self, apply_position_hint: bool, defer: bool) { if self.status.get() == SeatConstraintStatus::Active { self.seat.constraint.take(); - self.handle_position_hint(apply_position_hint); + self.handle_position_hint(apply_position_hint, defer); if let Some(owner) = self.owner.get() { owner.send_disabled(); } @@ -80,7 +80,7 @@ impl SeatConstraint { } } - fn handle_position_hint(&self, apply: bool) { + fn handle_position_hint(&self, apply: bool, defer: bool) { let Some((x, y)) = self.position_hint.take() else { return; }; @@ -96,6 +96,7 @@ impl SeatConstraint { self.client.state.now_usec(), x.apply_fract(x_int), y.apply_fract(y_int), + defer, ); } @@ -140,7 +141,7 @@ impl SeatConstraint { } fn detach(&self) { - self.deactivate(true); + self.deactivate(true, false); self.owner.take(); self.surface.constraints.remove(&self.seat.id); } diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 299199ad..f227b80a 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -1630,7 +1630,7 @@ impl WlSurface { pub fn detach_node(&self, set_invisible: bool) { for (_, constraint) in &self.constraints { - constraint.deactivate(true); + constraint.deactivate(true, true); } for (_, inhibitor) in &self.idle_inhibitors { inhibitor.deactivate();