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

View file

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