Correct pointer constraint activation logic

Internally it uses the pointer focus, so make sure we have up-to-date
focus before setting it.
This commit is contained in:
Ivan Molodetskikh
2024-11-03 09:32:58 +03:00
parent 7baf10b751
commit 9193245871
3 changed files with 27 additions and 22 deletions
+6 -5
View File
@@ -137,11 +137,12 @@ impl TabletSeatHandler for State {
delegate_tablet_manager!(State); delegate_tablet_manager!(State);
impl PointerConstraintsHandler for State { impl PointerConstraintsHandler for State {
fn new_constraint(&mut self, _surface: &WlSurface, pointer: &PointerHandle<Self>) { fn new_constraint(&mut self, _surface: &WlSurface, _pointer: &PointerHandle<Self>) {
self.niri.maybe_activate_pointer_constraint( // Pointer constraints track pointer focus internally, so make sure it's up to date before
pointer.current_location(), // activating a new one.
&self.niri.pointer_contents, self.refresh_pointer_contents();
);
self.niri.maybe_activate_pointer_constraint();
} }
fn cursor_position_hint( fn cursor_position_hint(
+5 -4
View File
@@ -1448,9 +1448,6 @@ impl State {
self.niri.handle_focus_follows_mouse(&under); self.niri.handle_focus_follows_mouse(&under);
// Activate a new confinement if necessary.
self.niri.maybe_activate_pointer_constraint(new_pos, &under);
self.niri.pointer_contents.clone_from(&under); self.niri.pointer_contents.clone_from(&under);
pointer.motion( pointer.motion(
@@ -1475,6 +1472,9 @@ impl State {
pointer.frame(self); pointer.frame(self);
// Activate a new confinement if necessary.
self.niri.maybe_activate_pointer_constraint();
// Redraw to update the cursor position. // Redraw to update the cursor position.
// FIXME: redraw only outputs overlapping the cursor. // FIXME: redraw only outputs overlapping the cursor.
self.niri.queue_redraw_all(); self.niri.queue_redraw_all();
@@ -1513,7 +1513,6 @@ impl State {
self.niri.handle_focus_follows_mouse(&under); self.niri.handle_focus_follows_mouse(&under);
self.niri.maybe_activate_pointer_constraint(pos, &under);
self.niri.pointer_contents.clone_from(&under); self.niri.pointer_contents.clone_from(&under);
pointer.motion( pointer.motion(
@@ -1528,6 +1527,8 @@ impl State {
pointer.frame(self); pointer.frame(self);
self.niri.maybe_activate_pointer_constraint();
// We moved the pointer, show it. // We moved the pointer, show it.
self.niri.pointer_hidden = false; self.niri.pointer_hidden = false;
+16 -13
View File
@@ -588,8 +588,6 @@ impl State {
pub fn move_cursor(&mut self, location: Point<f64, Logical>) { pub fn move_cursor(&mut self, location: Point<f64, Logical>) {
let under = self.niri.contents_under(location); let under = self.niri.contents_under(location);
self.niri
.maybe_activate_pointer_constraint(location, &under);
self.niri.pointer_contents.clone_from(&under); self.niri.pointer_contents.clone_from(&under);
let pointer = &self.niri.seat.get_pointer().unwrap(); let pointer = &self.niri.seat.get_pointer().unwrap();
@@ -604,6 +602,8 @@ impl State {
); );
pointer.frame(self); pointer.frame(self);
self.niri.maybe_activate_pointer_constraint();
// We do not show the pointer on programmatic or keyboard movement. // We do not show the pointer on programmatic or keyboard movement.
// FIXME: granular // FIXME: granular
@@ -735,9 +735,6 @@ impl State {
return false; return false;
} }
self.niri
.maybe_activate_pointer_constraint(location, &under);
self.niri.pointer_contents.clone_from(&under); self.niri.pointer_contents.clone_from(&under);
pointer.motion( pointer.motion(
@@ -750,6 +747,8 @@ impl State {
}, },
); );
self.niri.maybe_activate_pointer_constraint();
true true
} }
@@ -4517,17 +4516,21 @@ impl Niri {
output_state.lock_surface = Some(surface); output_state.lock_surface = Some(surface);
} }
pub fn maybe_activate_pointer_constraint( /// Activates the pointer constraint if necessary according to the current pointer contents.
&self, ///
new_pos: Point<f64, Logical>, /// Make sure the pointer location and contents are up to date before calling this.
new_under: &PointContents, pub fn maybe_activate_pointer_constraint(&self) {
) { let pointer = self.seat.get_pointer().unwrap();
let Some((surface, surface_loc)) = &new_under.surface else { let pointer_pos = pointer.current_location();
let Some((surface, surface_loc)) = &self.pointer_contents.surface else {
return; return;
}; };
if self.pointer_grab_ongoing { if self.pointer_grab_ongoing {
return; return;
} }
let pointer = &self.seat.get_pointer().unwrap(); let pointer = &self.seat.get_pointer().unwrap();
with_pointer_constraint(surface, pointer, |constraint| { with_pointer_constraint(surface, pointer, |constraint| {
let Some(constraint) = constraint else { return }; let Some(constraint) = constraint else { return };
@@ -4538,8 +4541,8 @@ impl Niri {
// Constraint does not apply if not within region. // Constraint does not apply if not within region.
if let Some(region) = constraint.region() { if let Some(region) = constraint.region() {
let new_pos_within_surface = new_pos - *surface_loc; let pos_within_surface = pointer_pos - *surface_loc;
if !region.contains(new_pos_within_surface.to_i32_round()) { if !region.contains(pos_within_surface.to_i32_round()) {
return; return;
} }
} }