Skip to content

Commit

Permalink
Call *Grab::unset when grab is removed due to surface not being alive
Browse files Browse the repository at this point in the history
It seems I missed one place where a grab could be removed.

This fixes an issue on cosmic-comp where a surface being destroyed
during a DnD drag from that surface would result in the DnD surface
still displaying. (For instance, closing cosmic-workspaces with a
keybinding while dragging).

(I guess the `&mut D` argument to `with_grab` is needed after all... I'll
probably not create another dozen PRs adding and removing it again. It's
an internal API anyway.)
  • Loading branch information
ids1024 authored and Drakulix committed Apr 18, 2024
1 parent db380f5 commit 49ba425
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 55 deletions.
27 changes: 20 additions & 7 deletions src/input/keyboard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,9 @@ impl<D: SeatHandler + 'static> KbdInternal<D> {
(modifiers_changed, leds_changed)
}

fn with_grab<F>(&mut self, seat: &Seat<D>, f: F)
fn with_grab<F>(&mut self, data: &mut D, seat: &Seat<D>, f: F)
where
F: FnOnce(&mut KeyboardInnerHandle<'_, D>, &mut dyn KeyboardGrab<D>),
F: FnOnce(&mut D, &mut KeyboardInnerHandle<'_, D>, &mut dyn KeyboardGrab<D>),
{
let mut grab = std::mem::replace(&mut self.grab, GrabStatus::Borrowed);
match grab {
Expand All @@ -218,15 +218,28 @@ impl<D: SeatHandler + 'static> KbdInternal<D> {
// If this grab is associated with a surface that is no longer alive, discard it
if let Some(ref surface) = handler.start_data().focus {
if !surface.alive() {
handler.unset(data);
self.grab = GrabStatus::None;
f(&mut KeyboardInnerHandle { inner: self, seat }, &mut DefaultGrab);
f(
data,
&mut KeyboardInnerHandle { inner: self, seat },
&mut DefaultGrab,
);
return;
}
}
f(&mut KeyboardInnerHandle { inner: self, seat }, &mut **handler);
f(
data,
&mut KeyboardInnerHandle { inner: self, seat },
&mut **handler,
);
}
GrabStatus::None => {
f(&mut KeyboardInnerHandle { inner: self, seat }, &mut DefaultGrab);
f(
data,
&mut KeyboardInnerHandle { inner: self, seat },
&mut DefaultGrab,
);
}
}

Expand Down Expand Up @@ -937,7 +950,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
// forward to client if no keybinding is triggered
let seat = self.get_seat(data);
let modifiers = mods_changed.then_some(guard.mods_state);
guard.with_grab(&seat, |handle, grab| {
guard.with_grab(data, &seat, |data, handle, grab| {
grab.input(data, handle, keycode, state, modifiers, serial, time);
});
if guard.focus.is_some() {
Expand All @@ -958,7 +971,7 @@ impl<D: SeatHandler + 'static> KeyboardHandle<D> {
let mut guard = self.arc.internal.lock().unwrap();
guard.pending_focus = focus.clone();
let seat = self.get_seat(data);
guard.with_grab(&seat, |handle, grab| {
guard.with_grab(data, &seat, |data, handle, grab| {
grab.set_focus(data, handle, focus, serial);
});
}
Expand Down
119 changes: 81 additions & 38 deletions src/input/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
let mut inner = self.inner.lock().unwrap();
inner.pending_focus = focus.clone();
let seat = self.get_seat(data);
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.motion(data, handle, focus, event);
});
}
Expand All @@ -264,7 +264,7 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
let mut inner = self.inner.lock().unwrap();
inner.pending_focus = focus.clone();
let seat = self.get_seat(data);
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.relative_motion(data, handle, focus, event);
});
}
Expand All @@ -285,7 +285,7 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
}
}
let seat = self.get_seat(data);
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.button(data, handle, event);
});
}
Expand All @@ -296,9 +296,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn axis(&self, data: &mut D, details: AxisFrame) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.axis(data, handle, details);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.axis(data, handle, details);
});
}

/// End of a pointer frame
Expand All @@ -307,9 +310,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn frame(&self, data: &mut D) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.frame(data, handle);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.frame(data, handle);
});
}

/// Notify about swipe gesture begin
Expand All @@ -320,9 +326,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_swipe_begin(&self, data: &mut D, event: &GestureSwipeBeginEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_swipe_begin(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_swipe_begin(data, handle, event);
});
}

/// Notify about swipe gesture update
Expand All @@ -333,9 +342,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_swipe_update(&self, data: &mut D, event: &GestureSwipeUpdateEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_swipe_update(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_swipe_update(data, handle, event);
});
}

/// Notify about swipe gesture end
Expand All @@ -346,9 +358,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_swipe_end(&self, data: &mut D, event: &GestureSwipeEndEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_swipe_end(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_swipe_end(data, handle, event);
});
}

/// Notify about pinch gesture begin
Expand All @@ -359,9 +374,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_pinch_begin(&self, data: &mut D, event: &GesturePinchBeginEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_pinch_begin(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_pinch_begin(data, handle, event);
});
}

/// Notify about pinch gesture update
Expand All @@ -372,9 +390,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_pinch_update(&self, data: &mut D, event: &GesturePinchUpdateEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_pinch_update(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_pinch_update(data, handle, event);
});
}

/// Notify about pinch gesture end
Expand All @@ -385,9 +406,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_pinch_end(&self, data: &mut D, event: &GesturePinchEndEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_pinch_end(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_pinch_end(data, handle, event);
});
}

/// Notify about hold gesture begin
Expand All @@ -398,9 +422,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_hold_begin(&self, data: &mut D, event: &GestureHoldBeginEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_hold_begin(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_hold_begin(data, handle, event);
});
}

/// Notify about hold gesture end
Expand All @@ -411,9 +438,12 @@ impl<D: SeatHandler + 'static> PointerHandle<D> {
#[instrument(level = "trace", parent = &self.span, skip(self, data))]
pub fn gesture_hold_end(&self, data: &mut D, event: &GestureHoldEndEvent) {
let seat = self.get_seat(data);
self.inner.lock().unwrap().with_grab(&seat, |handle, grab| {
grab.gesture_hold_end(data, handle, event);
});
self.inner
.lock()
.unwrap()
.with_grab(data, &seat, |data, handle, grab| {
grab.gesture_hold_end(data, handle, event);
});
}

/// Access the current location of this pointer in the global space
Expand Down Expand Up @@ -833,9 +863,9 @@ impl<D: SeatHandler + 'static> PointerInternal<D> {
}
}

fn with_grab<F>(&mut self, seat: &Seat<D>, f: F)
fn with_grab<F>(&mut self, data: &mut D, seat: &Seat<D>, f: F)
where
F: FnOnce(&mut PointerInnerHandle<'_, D>, &mut dyn PointerGrab<D>),
F: FnOnce(&mut D, &mut PointerInnerHandle<'_, D>, &mut dyn PointerGrab<D>),
{
let mut grab = std::mem::replace(&mut self.grab, GrabStatus::Borrowed);
match grab {
Expand All @@ -844,15 +874,28 @@ impl<D: SeatHandler + 'static> PointerInternal<D> {
// If this grab is associated with a surface that is no longer alive, discard it
if let Some((ref focus, _)) = handler.start_data().focus {
if !focus.alive() {
handler.unset(data);
self.grab = GrabStatus::None;
f(&mut PointerInnerHandle { inner: self, seat }, &mut DefaultGrab);
f(
data,
&mut PointerInnerHandle { inner: self, seat },
&mut DefaultGrab,
);
return;
}
}
f(&mut PointerInnerHandle { inner: self, seat }, &mut **handler);
f(
data,
&mut PointerInnerHandle { inner: self, seat },
&mut **handler,
);
}
GrabStatus::None => {
f(&mut PointerInnerHandle { inner: self, seat }, &mut DefaultGrab);
f(
data,
&mut PointerInnerHandle { inner: self, seat },
&mut DefaultGrab,
);
}
}

Expand Down
29 changes: 19 additions & 10 deletions src/input/touch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ impl<D: SeatHandler + 'static> TouchHandle<D> {
let mut inner = self.inner.lock().unwrap();
let seat = self.get_seat(data);
let seq = inner.seq_counter.next_serial();
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.down(data, handle, focus, event, seq);
});
}
Expand All @@ -289,7 +289,7 @@ impl<D: SeatHandler + 'static> TouchHandle<D> {
let mut inner = self.inner.lock().unwrap();
let seat = self.get_seat(data);
let seq = inner.seq_counter.next_serial();
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.up(data, handle, event, seq);
});
}
Expand All @@ -315,7 +315,7 @@ impl<D: SeatHandler + 'static> TouchHandle<D> {
let mut inner = self.inner.lock().unwrap();
let seat = self.get_seat(data);
let seq = inner.seq_counter.next_serial();
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.motion(data, handle, focus, event, seq);
});
}
Expand All @@ -327,7 +327,7 @@ impl<D: SeatHandler + 'static> TouchHandle<D> {
let mut inner = self.inner.lock().unwrap();
let seat = self.get_seat(data);
let seq = inner.seq_counter.next_serial();
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.frame(data, handle, seq);
});
}
Expand All @@ -341,7 +341,7 @@ impl<D: SeatHandler + 'static> TouchHandle<D> {
let mut inner = self.inner.lock().unwrap();
let seat = self.get_seat(data);
let seq = inner.seq_counter.next_serial();
inner.with_grab(&seat, |handle, grab| {
inner.with_grab(data, &seat, |data, handle, grab| {
grab.cancel(data, handle, seq);
});
}
Expand Down Expand Up @@ -572,9 +572,9 @@ impl<D: SeatHandler + 'static> TouchInternal<D> {
}
}

fn with_grab<F>(&mut self, seat: &Seat<D>, f: F)
fn with_grab<F>(&mut self, data: &mut D, seat: &Seat<D>, f: F)
where
F: FnOnce(&mut TouchInnerHandle<'_, D>, &mut dyn TouchGrab<D>),
F: FnOnce(&mut D, &mut TouchInnerHandle<'_, D>, &mut dyn TouchGrab<D>),
{
let mut grab = std::mem::replace(&mut self.grab, GrabStatus::Borrowed);
match grab {
Expand All @@ -583,17 +583,26 @@ impl<D: SeatHandler + 'static> TouchInternal<D> {
// If this grab is associated with a surface that is no longer alive, discard it
if let Some((ref focus, _)) = handler.start_data().focus {
if !focus.alive() {
handler.unset(data);
self.grab = GrabStatus::None;
let mut default_grab = (self.default_grab)();
f(&mut TouchInnerHandle { inner: self, seat }, &mut *default_grab);
f(
data,
&mut TouchInnerHandle { inner: self, seat },
&mut *default_grab,
);
return;
}
}
f(&mut TouchInnerHandle { inner: self, seat }, &mut **handler);
f(data, &mut TouchInnerHandle { inner: self, seat }, &mut **handler);
}
GrabStatus::None => {
let mut default_grab = (self.default_grab)();
f(&mut TouchInnerHandle { inner: self, seat }, &mut *default_grab);
f(
data,
&mut TouchInnerHandle { inner: self, seat },
&mut *default_grab,
);
}
}

Expand Down

0 comments on commit 49ba425

Please sign in to comment.