mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 14:49:06 -04:00
Avoid repaints on device mouse motion outside window (#7866)
## Summary - Ignore raw device mouse motion unless the window is focused and the pointer is inside it - Also handles pointers starting down and then moving into or out of the window (drag & drop) - Prevents global mouse motion from triggering continuous repaint loops - Applies to both glow and wgpu backends ## Testing - I ran the check script, nothing seemed to fail --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
@@ -448,12 +448,21 @@ impl WinitApp for GlowWinitApp<'_> {
|
||||
if let Some(viewport) = glutin
|
||||
.focused_viewport
|
||||
.and_then(|viewport| glutin.viewports.get_mut(&viewport))
|
||||
&& let Some(window) = viewport.window.as_ref()
|
||||
{
|
||||
if let Some(egui_winit) = viewport.egui_winit.as_mut() {
|
||||
egui_winit.on_mouse_motion(delta);
|
||||
if !window.has_focus()
|
||||
&& !viewport
|
||||
.egui_winit
|
||||
.as_ref()
|
||||
.map(|state| state.is_any_pointer_button_down())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(EventResult::Wait);
|
||||
}
|
||||
|
||||
if let Some(window) = viewport.window.as_ref() {
|
||||
if let Some(egui_winit) = viewport.egui_winit.as_mut()
|
||||
&& egui_winit.on_mouse_motion(delta)
|
||||
{
|
||||
return Ok(EventResult::RepaintNext(window.id()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,12 +454,21 @@ impl WinitApp for WgpuWinitApp<'_> {
|
||||
if let Some(viewport) = shared
|
||||
.focused_viewport
|
||||
.and_then(|viewport| shared.viewports.get_mut(&viewport))
|
||||
&& let Some(window) = viewport.window.as_ref()
|
||||
{
|
||||
if let Some(egui_winit) = viewport.egui_winit.as_mut() {
|
||||
egui_winit.on_mouse_motion(delta);
|
||||
if !window.has_focus()
|
||||
&& !viewport
|
||||
.egui_winit
|
||||
.as_ref()
|
||||
.map(|state| state.is_any_pointer_button_down())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(EventResult::Wait);
|
||||
}
|
||||
|
||||
if let Some(window) = viewport.window.as_ref() {
|
||||
if let Some(egui_winit) = viewport.egui_winit.as_mut()
|
||||
&& egui_winit.on_mouse_motion(delta)
|
||||
{
|
||||
return Ok(EventResult::RepaintNext(window.id()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,11 +640,27 @@ impl State {
|
||||
self.has_sent_ime_enabled = false;
|
||||
}
|
||||
|
||||
pub fn on_mouse_motion(&mut self, delta: (f64, f64)) {
|
||||
/// Returns `true` if the event was sent to egui.
|
||||
pub fn on_mouse_motion(&mut self, delta: (f64, f64)) -> bool {
|
||||
if !self.is_pointer_in_window() && !self.any_pointer_button_down {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.egui_input.events.push(egui::Event::MouseMoved(Vec2 {
|
||||
x: delta.0 as f32,
|
||||
y: delta.1 as f32,
|
||||
}));
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns `true` when the pointer is currently inside the window.
|
||||
pub fn is_pointer_in_window(&self) -> bool {
|
||||
self.pointer_pos_in_points.is_some()
|
||||
}
|
||||
|
||||
/// Returns `true` if any pointer button is currently held down.
|
||||
pub fn is_any_pointer_button_down(&self) -> bool {
|
||||
self.any_pointer_button_down
|
||||
}
|
||||
|
||||
/// Call this when there is a new [`accesskit::ActionRequest`].
|
||||
|
||||
@@ -97,12 +97,12 @@ You should add the following to your `.gitignore`:
|
||||
* …have a low resolution to avoid growth in repo size
|
||||
* …have a low comparison threshold to avoid the test passing despite unwanted differences (the default threshold should be fine for most usecases!)
|
||||
|
||||
### What do do when CI / another computer produces a different image?
|
||||
### What to do when CI / another computer produces a different image?
|
||||
|
||||
The default tolerance settings should be fine for almost all gui comparison tests.
|
||||
However, especially when you're using custom rendering, you may observe images difference with different setups leading to unexpected test failures.
|
||||
|
||||
First check whether the difference is due to a change in enabled rendering features, potentially due to difference in hardware (/software renderer) capabilitites.
|
||||
First check whether the difference is due to a change in enabled rendering features, potentially due to difference in hardware (/software renderer) capabilities.
|
||||
Generally you should carefully enforcing the same set of features for all test runs, but this may happen nonetheless.
|
||||
|
||||
Once you validated that the differences are miniscule and hard to avoid, you can try to _carefully_ adjust the comparison tolerance setting (`SnapshotOptions::threshold`, TODO([#5683](https://github.com/emilk/egui/issues/5683)): as well as number of pixels allowed to differ) for the specific test.
|
||||
|
||||
Reference in New Issue
Block a user