Skip to content

Commit

Permalink
Fix menus and interactive popups not closing when framerate was low (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Jul 2, 2024
1 parent 8ef0e85 commit fcb7764
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
22 changes: 21 additions & 1 deletion crates/egui/src/input_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,9 @@ pub struct PointerState {
/// Current velocity of pointer.
velocity: Vec2,

/// Current direction of pointer.
direction: Vec2,

/// Recent movement of the pointer.
/// Used for calculating velocity of pointer.
pos_history: History<Pos2>,
Expand Down Expand Up @@ -774,7 +777,8 @@ impl Default for PointerState {
delta: Vec2::ZERO,
motion: None,
velocity: Vec2::ZERO,
pos_history: History::new(0..1000, 0.1),
direction: Vec2::ZERO,
pos_history: History::new(2..1000, 0.1),
down: Default::default(),
press_origin: None,
press_start_time: None,
Expand Down Expand Up @@ -889,6 +893,7 @@ impl PointerState {
// When dragging a slider and the mouse leaves the viewport, we still want the drag to work,
// so we don't treat this as a `PointerEvent::Released`.
// NOTE: we do NOT clear `self.interact_pos` here. It will be cleared next frame.
self.pos_history.clear();
}
Event::MouseMoved(delta) => *self.motion.get_or_insert(Vec2::ZERO) += *delta,
_ => {}
Expand Down Expand Up @@ -920,6 +925,8 @@ impl PointerState {
self.last_move_time = time;
}

self.direction = self.pos_history.velocity().unwrap_or_default().normalized();

self.started_decidedly_dragging = self.is_decidedly_dragging() && !was_decidedly_dragging;

self
Expand All @@ -944,11 +951,22 @@ impl PointerState {
}

/// Current velocity of pointer.
///
/// This is smoothed over a few frames,
/// but can be ZERO when frame-rate is bad.
#[inline(always)]
pub fn velocity(&self) -> Vec2 {
self.velocity
}

/// Current direction of the pointer.
///
/// This is less sensitive to bad framerate than [`Self::velocity`].
#[inline(always)]
pub fn direction(&self) -> Vec2 {
self.direction
}

/// Where did the current click/drag originate?
/// `None` if no mouse button is down.
#[inline(always)]
Expand Down Expand Up @@ -1284,6 +1302,7 @@ impl PointerState {
delta,
motion,
velocity,
direction,
pos_history: _,
down,
press_origin,
Expand All @@ -1304,6 +1323,7 @@ impl PointerState {
"velocity: [{:3.0} {:3.0}] points/sec",
velocity.x, velocity.y
));
ui.label(format!("direction: {direction:?}"));
ui.label(format!("down: {down:#?}"));
ui.label(format!("press_origin: {press_origin:?}"));
ui.label(format!("press_start_time: {press_start_time:?} s"));
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ impl MenuState {
if let Some(sub_menu) = self.current_submenu() {
if let Some(pos) = pointer.hover_pos() {
let rect = sub_menu.read().rect;
return rect.intersects_ray(pos, pointer.velocity().normalized());
return rect.intersects_ray(pos, pointer.direction().normalized());
}
}
false
Expand Down
6 changes: 3 additions & 3 deletions crates/egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,9 +594,9 @@ impl Response {
let is_tooltip_open = self.is_tooltip_open();

if is_tooltip_open {
let (pointer_pos, pointer_vel) = self
let (pointer_pos, pointer_dir) = self
.ctx
.input(|i| (i.pointer.hover_pos(), i.pointer.velocity()));
.input(|i| (i.pointer.hover_pos(), i.pointer.direction()));

if let Some(pointer_pos) = pointer_pos {
if self.rect.contains(pointer_pos) {
Expand Down Expand Up @@ -624,7 +624,7 @@ impl Response {

if let Some(pos) = pointer_pos {
let pointer_in_area_or_on_the_way_there = rect.contains(pos)
|| rect.intersects_ray(pos, pointer_vel.normalized());
|| rect.intersects_ray(pos, pointer_dir.normalized());

if pointer_in_area_or_on_the_way_there {
return true;
Expand Down

0 comments on commit fcb7764

Please sign in to comment.