From d14fc0455aa586a3b6b61278ac14ebafc99977de Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 27 Dec 2024 14:39:02 +0100 Subject: [PATCH] Fix interactive widgets sometimes being incorrectly marked as hovered An interactive widget should only be marked hovered if a click/drag would start an interaction with it. egui 0.30 introduced a feature where a thin interactive widget could be hit even if it was partially behind a larger interactive widget. Unfortunately, this introduced a bug where the top widget would still be marked as hovered, even though a click would go through to the thin widget below. This bug was most notacible when trying to reisize a window by dragging its corner, which often would result in dragging one of its sides instead. This PR fixes this bug. --- crates/egui/src/interaction.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/egui/src/interaction.rs b/crates/egui/src/interaction.rs index 04f8f7dbf6f4..22ec8ebc5a57 100644 --- a/crates/egui/src/interaction.rs +++ b/crates/egui/src/interaction.rs @@ -256,10 +256,6 @@ pub(crate) fn interact( // In that case we want to hover _both_ widgets, // otherwise we won't see tooltips for the label. // - // Because of how `Ui` work, we will often allocate the `Ui` rect - // _after_ adding the children in it (once we know the size it will occopy) - // so we will also have a lot of such `Ui` widgets rects covering almost any widget. - // // So: we want to hover _all_ widgets above the interactive widget (if any), // but none below it (an interactive widget stops the hover search). // @@ -275,8 +271,16 @@ pub(crate) fn interact( let mut hovered: IdSet = hits.click.iter().chain(&hits.drag).map(|w| w.id).collect(); for w in &hits.contains_pointer { - if top_interactive_order <= order(w.id).unwrap_or(0) { - hovered.insert(w.id); + let is_interactive = w.sense.click || w.sense.drag; + if is_interactive { + // The only interactive widgets we mark as hovered are the ones + // in `hits.click` and `hits.drag`! + } else { + let is_on_top_of_the_interactive_widget = + top_interactive_order <= order(w.id).unwrap_or(0); + if is_on_top_of_the_interactive_widget { + hovered.insert(w.id); + } } }