Skip to content

Commit 7c34289

Browse files
committed
fix(mmserver): correctly handle an edge case with pointer locks
If the app destroyed a constraint and then immediately created a new one, we would return a wayland protocol error.
1 parent 4ce202d commit 7c34289

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

mm-server/src/compositor/seat.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,18 @@ impl Seat {
510510
}
511511

512512
pub fn has_lock(&self, wl_surface: &wl_surface::WlSurface) -> bool {
513-
self.inactive_pointer_locks.contains_key(wl_surface)
514-
|| self.pointer_lock.as_ref().map(|(surf, _)| surf) == Some(wl_surface)
513+
if self
514+
.pointer_lock
515+
.as_ref()
516+
.is_some_and(|(surf, lock)| surf == wl_surface && !lock.defunct)
517+
{
518+
return true;
519+
}
520+
521+
// Check for inactive locks that aren't already destroyed.
522+
self.inactive_pointer_locks
523+
.get(wl_surface)
524+
.is_some_and(|lock| !lock.defunct)
515525
}
516526

517527
pub fn create_lock(
@@ -565,7 +575,10 @@ impl State {
565575
let focus = seat.pointer_focus();
566576

567577
if let Some((wl_surface, lock)) = &seat.pointer_lock {
568-
if Some(wl_surface) == focus.as_ref() && lock.wp_locked_pointer.is_alive() {
578+
if !lock.defunct
579+
&& lock.wp_locked_pointer.is_alive()
580+
&& Some(wl_surface) == focus.as_ref()
581+
{
569582
// Same surface, active lock, nothing to do.
570583
return;
571584
}
@@ -575,7 +588,7 @@ impl State {
575588
lock.wp_locked_pointer.unlocked();
576589

577590
let lock_clone = lock.wp_locked_pointer.clone();
578-
if lock.wp_locked_pointer.is_alive() && !lock.oneshot {
591+
if !lock.defunct && !lock.oneshot && lock.wp_locked_pointer.is_alive() {
579592
seat.inactive_pointer_locks.insert(surf, lock);
580593
}
581594

0 commit comments

Comments
 (0)