From 9624de6c4131f712c189949c68cfd9d26655fd00 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 11 May 2022 20:56:57 +0200 Subject: [PATCH] Fix dead-lock when alt-tabbing while also showing a tooltip (#1618) Closes https://github.com/emilk/egui/issues/1609 --- CHANGELOG.md | 5 +++++ egui/src/containers/popup.rs | 18 +++++++++++------- egui/src/frame_state.rs | 9 ++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b49bad767c..a93cb55131d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,14 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui-w ## Unreleased +### Added ⭐ * Add `*_released` & `*_clicked` methods for `PointerState` ([#1582](https://github.com/emilk/egui/pull/1582)). * Optimize painting of filled circles (e.g. for scatter plots) by 10x or more ([#1616](https://github.com/emilk/egui/pull/1616)). + +### Fixed 🐛 * Fixed `ImageButton`'s changing background padding on hover ([#1595](https://github.com/emilk/egui/pull/1595)). +* Fix dead-lock when alt-tabbing while also showing a tooltip ([#1618](https://github.com/emilk/egui/pull/1618)). + ## 0.18.1 - 2022-05-01 * Change `Shape::Callback` from `&dyn Any` to `&mut dyn Any` to support more backends. diff --git a/egui/src/containers/popup.rs b/egui/src/containers/popup.rs index fa00f3cf93f..9e35ba02e2b 100644 --- a/egui/src/containers/popup.rs +++ b/egui/src/containers/popup.rs @@ -160,13 +160,13 @@ fn show_tooltip_at_avoid_dyn<'c, R>( let mut tooltip_rect = Rect::NOTHING; let mut count = 0; - let mut position = if let Some((stored_id, stored_tooltip_rect, stored_count)) = - ctx.frame_state().tooltip_rect - { + let stored = ctx.frame_state().tooltip_rect; + + let mut position = if let Some(stored) = stored { // if there are multiple tooltips open they should use the same id for the `tooltip_size` caching to work. - id = stored_id; - tooltip_rect = stored_tooltip_rect; - count = stored_count; + id = stored.id; + tooltip_rect = stored.rect; + count = stored.count; avoid_rect = avoid_rect.union(tooltip_rect); if above { tooltip_rect.left_top() @@ -214,7 +214,11 @@ fn show_tooltip_at_avoid_dyn<'c, R>( state.set_tooltip_size(id, count, response.rect.size()); state.store(ctx); - ctx.frame_state().tooltip_rect = Some((id, tooltip_rect.union(response.rect), count + 1)); + ctx.frame_state().tooltip_rect = Some(crate::frame_state::TooltipRect { + id, + rect: tooltip_rect.union(response.rect), + count: count + 1, + }); Some(inner) } diff --git a/egui/src/frame_state.rs b/egui/src/frame_state.rs index 8983aad62ba..829d0d58701 100644 --- a/egui/src/frame_state.rs +++ b/egui/src/frame_state.rs @@ -2,6 +2,13 @@ use std::ops::RangeInclusive; use crate::*; +#[derive(Clone, Copy, Debug)] +pub(crate) struct TooltipRect { + pub id: Id, + pub rect: Rect, + pub count: usize, +} + /// State that is collected during a frame and then cleared. /// Short-term (single frame) memory. #[derive(Clone)] @@ -25,7 +32,7 @@ pub(crate) struct FrameState { /// If a tooltip has been shown this frame, where was it? /// This is used to prevent multiple tooltips to cover each other. /// Initialized to `None` at the start of each frame. - pub(crate) tooltip_rect: Option<(Id, Rect, usize)>, + pub(crate) tooltip_rect: Option, /// Set to [`InputState::scroll_delta`] on the start of each frame. ///