Skip to content

Web demo loses mouse cursor position when dragging off the window #3157

@pfgithub

Description

@pfgithub

Describe the bug
While dragging in the web demo if the mouse goes off the window egui stops receiving mouse events

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://www.egui.rs/
  2. Click '3d painting'
  3. Click and drag the triangle and move your mouse off the window
  4. The triangle stops dragging when the mouse leaves the window

Expected behavior
The triangle should keep dragging even with the mouse off the window

Screenshots

firefox_qLVcHJKFpk.mp4

The triangle stops rotating when the mouse goes off the screen, even though the mouse is held down

Desktop (please complete the following information):
All

Smartphone (please complete the following information):
All

Additional context
Event listeners registered on document.body will continue to give mousemove/touchmove events even with the cursor off the screen, but eframe only registers event listeners on the canvas element.

runner_ref.add_event_listener(
&canvas,
"mousedown",
|event: web_sys::MouseEvent, runner: &mut AppRunner| {
if let Some(button) = button_from_mouse_event(&event) {
let pos = pos_from_mouse_event(runner.canvas_id(), &event);
let modifiers = runner.input.raw.modifiers;
runner.input.raw.events.push(egui::Event::PointerButton {
pos,
button,
pressed: true,
modifiers,
});
runner.needs_repaint.repaint_asap();
}
event.stop_propagation();
// Note: prevent_default breaks VSCode tab focusing, hence why we don't call it here.
},
)?;
runner_ref.add_event_listener(
&canvas,
"mousemove",
|event: web_sys::MouseEvent, runner| {
let pos = pos_from_mouse_event(runner.canvas_id(), &event);
runner.input.raw.events.push(egui::Event::PointerMoved(pos));
runner.needs_repaint.repaint_asap();
event.stop_propagation();
event.prevent_default();
},
)?;
runner_ref.add_event_listener(&canvas, "mouseup", |event: web_sys::MouseEvent, runner| {
if let Some(button) = button_from_mouse_event(&event) {
let pos = pos_from_mouse_event(runner.canvas_id(), &event);
let modifiers = runner.input.raw.modifiers;
runner.input.raw.events.push(egui::Event::PointerButton {
pos,
button,
pressed: false,
modifiers,
});
runner.needs_repaint.repaint_asap();
text_agent::update_text_agent(runner);
}
event.stop_propagation();
event.prevent_default();
})?;
runner_ref.add_event_listener(
&canvas,
"mouseleave",
|event: web_sys::MouseEvent, runner| {
runner.input.raw.events.push(egui::Event::PointerGone);
runner.needs_repaint.repaint_asap();
event.stop_propagation();
event.prevent_default();
},
)?;

This registers event listeners on the canvas element, but after mousedown/touchdown, event listeners need to be registered on the document element in order to continue receiving mousemove events as the mouse goes off the screen.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is brokenhelp wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions