Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
pfgithub opened this issue Jul 12, 2023 · 3 comments · Fixed by #4522
Closed

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

pfgithub opened this issue Jul 12, 2023 · 3 comments · Fixed by #4522
Labels
bug Something is broken help wanted Extra attention is needed

Comments

@pfgithub
Copy link

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.

@pfgithub pfgithub added the bug Something is broken label Jul 12, 2023
@emilk emilk added this to the Next Major Release milestone May 16, 2024
@emilk emilk self-assigned this May 21, 2024
@emilk emilk added the help wanted Extra attention is needed label May 21, 2024
@emilk
Copy link
Owner

emilk commented May 21, 2024

I tried registering mousemove on document.body, but the events still stop when dragging outside the canvas

@emilk emilk removed their assignment May 21, 2024
@pfgithub
Copy link
Author

pfgithub commented May 21, 2024

Sorry, I said the wrong thing. It should be on document (or document.documentElement) not document.body. Testing in the dev console, this continues to send events while dragging the mouse if it goes off the page (but not if you didn't start the drag on the page)

document.addEventListener("mousemove", e => console.log(e.clientX, e.clientY));

@emilk
Copy link
Owner

emilk commented May 21, 2024

Nice, that works! I just have to figure out what to do with mouseleave/Event::PointerGone now

emilk added a commit that referenced this issue May 22, 2024
* Closes #3157

If the mouse leaves the canvas when dragging a slider, the slider will
still move.

---

To support this, I had to revert #4419
Despite that, I fail to reproduce the two issues it claimed to solve:

* #4406 may have been solved in
another way by this PR
* #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`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants