fix: end slider drag when the pointer leaves the window

A popup does not deliver the button release if it happens outside the
window, so the drag stayed active after the pointer came back.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
KarstenKreh 2026-09-24 21:27:10 +02:00 • committed by Ashley Wulber
parent b2419520fe
commit 2157f9d159
2 changed files with 32 additions and 11 deletions

View file

@ -344,7 +344,7 @@ where
_renderer: &Renderer,
_clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let state = tree.state.downcast_mut::<State>();
@ -452,6 +452,8 @@ where
Event::Mouse(mouse::Event::ButtonReleased(
mouse::Button::Left,
))
| Event::Mouse(mouse::Event::CursorLeft)
| Event::Mouse(mouse::Event::CursorEntered)
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
if state.is_dragging {
@ -464,13 +466,20 @@ where
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
if state.is_dragging {
let _ = cursor
.land()
.position()
.and_then(locate)
.map(change);
let position = cursor.land().position();
let outside = position.is_none_or(|position| {
!viewport.contains(position)
});
shell.capture_event();
if outside {
if let Some(on_release) = self.on_release.clone() {
shell.publish(on_release);
}
state.is_dragging = false;
} else {
let _ = position.and_then(locate).map(change);
shell.capture_event();
}
}
}
Event::Mouse(mouse::Event::WheelScrolled { delta })

View file

@ -255,7 +255,7 @@ where
_renderer: &Renderer,
_clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
viewport: &Rectangle,
) {
let state = tree.state.downcast_mut::<State>();
let is_dragging = state.is_dragging;
@ -354,6 +354,8 @@ where
}
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left))
| Event::Mouse(mouse::Event::CursorLeft)
| Event::Mouse(mouse::Event::CursorEntered)
| Event::Touch(touch::Event::FingerLifted { .. })
| Event::Touch(touch::Event::FingerLost { .. }) => {
if is_dragging {
@ -366,10 +368,20 @@ where
Event::Mouse(mouse::Event::CursorMoved { .. })
| Event::Touch(touch::Event::FingerMoved { .. }) => {
if is_dragging {
let _ =
cursor.land().position().and_then(locate).map(change);
let position = cursor.land().position();
let outside = position.is_none_or(|position| {
!viewport.contains(position)
});
shell.capture_event();
if outside {
if let Some(on_release) = self.on_release.clone() {
shell.publish(on_release);
}
state.is_dragging = false;
} else {
let _ = position.and_then(locate).map(change);
shell.capture_event();
}
}
}
Event::Mouse(mouse::Event::WheelScrolled { delta })