mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Fix: still track mouse when dragging outside web canvas (#4522)
* Closes https://github.com/emilk/egui/issues/3157 If the mouse leaves the canvas when dragging a slider, the slider will still move. --- To support this, I had to revert https://github.com/emilk/egui/pull/4419 Despite that, I fail to reproduce the two issues it claimed to solve: * https://github.com/emilk/egui/issues/4406 may have been solved in another way by this PR * https://github.com/emilk/egui/issues/4418 I cannot reproduce on Mac. If it is still a problem, I think it should be solved by triggering a `PointerEvent::Released` when focus is lost (i.e. on alt-tab), and not on `PointerGone`
This commit is contained in:
@@ -284,6 +284,8 @@ pub(crate) fn install_color_scheme_change_event(runner_ref: &WebRunner) -> Resul
|
||||
|
||||
pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValue> {
|
||||
let canvas = runner_ref.try_lock().unwrap().canvas().clone();
|
||||
let window = web_sys::window().unwrap();
|
||||
let document = window.document().unwrap();
|
||||
|
||||
{
|
||||
let prevent_default_events = [
|
||||
@@ -333,8 +335,11 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||
},
|
||||
)?;
|
||||
|
||||
// NOTE: we register "mousemove" on `document` instead of just the canvas
|
||||
// in order to track a dragged mouse outside the canvas.
|
||||
// See https://github.com/emilk/egui/issues/3157
|
||||
runner_ref.add_event_listener(
|
||||
&canvas,
|
||||
&document,
|
||||
"mousemove",
|
||||
|event: web_sys::MouseEvent, runner| {
|
||||
let modifiers = modifiers_from_mouse_event(&event);
|
||||
@@ -347,31 +352,37 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||
},
|
||||
)?;
|
||||
|
||||
runner_ref.add_event_listener(&canvas, "mouseup", |event: web_sys::MouseEvent, runner| {
|
||||
let modifiers = modifiers_from_mouse_event(&event);
|
||||
runner.input.raw.modifiers = modifiers;
|
||||
if let Some(button) = button_from_mouse_event(&event) {
|
||||
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
||||
let modifiers = runner.input.raw.modifiers;
|
||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||
pos,
|
||||
button,
|
||||
pressed: false,
|
||||
modifiers,
|
||||
});
|
||||
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
||||
// See https://github.com/emilk/egui/issues/3157
|
||||
runner_ref.add_event_listener(
|
||||
&document,
|
||||
"mouseup",
|
||||
|event: web_sys::MouseEvent, runner| {
|
||||
let modifiers = modifiers_from_mouse_event(&event);
|
||||
runner.input.raw.modifiers = modifiers;
|
||||
if let Some(button) = button_from_mouse_event(&event) {
|
||||
let pos = pos_from_mouse_event(runner.canvas(), &event, runner.egui_ctx());
|
||||
let modifiers = runner.input.raw.modifiers;
|
||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||
pos,
|
||||
button,
|
||||
pressed: false,
|
||||
modifiers,
|
||||
});
|
||||
|
||||
// In Safari we are only allowed to write to the clipboard during the
|
||||
// event callback, which is why we run the app logic here and now:
|
||||
runner.logic();
|
||||
// In Safari we are only allowed to write to the clipboard during the
|
||||
// event callback, which is why we run the app logic here and now:
|
||||
runner.logic();
|
||||
|
||||
// Make sure we paint the output of the above logic call asap:
|
||||
runner.needs_repaint.repaint_asap();
|
||||
// Make sure we paint the output of the above logic call asap:
|
||||
runner.needs_repaint.repaint_asap();
|
||||
|
||||
text_agent::update_text_agent(runner);
|
||||
}
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
})?;
|
||||
text_agent::update_text_agent(runner);
|
||||
}
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
},
|
||||
)?;
|
||||
|
||||
runner_ref.add_event_listener(
|
||||
&canvas,
|
||||
@@ -412,8 +423,10 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||
},
|
||||
)?;
|
||||
|
||||
// Use `document` here to notice if the user drag outside of the canvas.
|
||||
// See https://github.com/emilk/egui/issues/3157
|
||||
runner_ref.add_event_listener(
|
||||
&canvas,
|
||||
&document,
|
||||
"touchmove",
|
||||
|event: web_sys::TouchEvent, runner| {
|
||||
let mut latest_touch_pos_id = runner.input.latest_touch_pos_id;
|
||||
@@ -434,28 +447,34 @@ pub(crate) fn install_canvas_events(runner_ref: &WebRunner) -> Result<(), JsValu
|
||||
},
|
||||
)?;
|
||||
|
||||
runner_ref.add_event_listener(&canvas, "touchend", |event: web_sys::TouchEvent, runner| {
|
||||
if let Some(pos) = runner.input.latest_touch_pos {
|
||||
let modifiers = runner.input.raw.modifiers;
|
||||
// First release mouse to click:
|
||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||
pos,
|
||||
button: egui::PointerButton::Primary,
|
||||
pressed: false,
|
||||
modifiers,
|
||||
});
|
||||
// Then remove hover effect:
|
||||
runner.input.raw.events.push(egui::Event::PointerGone);
|
||||
// Use `document` here to notice if the user releases a drag outside of the canvas.
|
||||
// See https://github.com/emilk/egui/issues/3157
|
||||
runner_ref.add_event_listener(
|
||||
&document,
|
||||
"touchend",
|
||||
|event: web_sys::TouchEvent, runner| {
|
||||
if let Some(pos) = runner.input.latest_touch_pos {
|
||||
let modifiers = runner.input.raw.modifiers;
|
||||
// First release mouse to click:
|
||||
runner.input.raw.events.push(egui::Event::PointerButton {
|
||||
pos,
|
||||
button: egui::PointerButton::Primary,
|
||||
pressed: false,
|
||||
modifiers,
|
||||
});
|
||||
// Then remove hover effect:
|
||||
runner.input.raw.events.push(egui::Event::PointerGone);
|
||||
|
||||
push_touches(runner, egui::TouchPhase::End, &event);
|
||||
runner.needs_repaint.repaint_asap();
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
}
|
||||
push_touches(runner, egui::TouchPhase::End, &event);
|
||||
runner.needs_repaint.repaint_asap();
|
||||
event.stop_propagation();
|
||||
event.prevent_default();
|
||||
}
|
||||
|
||||
// Finally, focus or blur text agent to toggle mobile keyboard:
|
||||
text_agent::update_text_agent(runner);
|
||||
})?;
|
||||
// Finally, focus or blur text agent to toggle mobile keyboard:
|
||||
text_agent::update_text_agent(runner);
|
||||
},
|
||||
)?;
|
||||
|
||||
runner_ref.add_event_listener(
|
||||
&canvas,
|
||||
|
||||
Reference in New Issue
Block a user