Bug fix: clicking the edge of a menu button would flicker the menu

There was a very annoying bug where clicking the edge of a menu button
would open the menu and immediately close it.
This commit is contained in:
Emil Ernerfeldt 2021-08-21 21:59:25 +02:00
parent 0e457c4b06
commit 5a63419aa3
2 changed files with 18 additions and 5 deletions

View file

@ -159,6 +159,8 @@ impl CtxRef {
enabled: bool, enabled: bool,
) -> Response { ) -> Response {
let gap = 0.5; // Just to make sure we don't accidentally hover two things at once (a small eps should be sufficient). let gap = 0.5; // Just to make sure we don't accidentally hover two things at once (a small eps should be sufficient).
// Make it easier to click things:
let interact_rect = rect.expand2( let interact_rect = rect.expand2(
(0.5 * item_spacing - Vec2::splat(gap)) (0.5 * item_spacing - Vec2::splat(gap))
.at_least(Vec2::splat(0.0)) .at_least(Vec2::splat(0.0))

View file

@ -142,12 +142,23 @@ impl Response {
/// `true` if there was a click *outside* this widget this frame. /// `true` if there was a click *outside* this widget this frame.
pub fn clicked_elsewhere(&self) -> bool { pub fn clicked_elsewhere(&self) -> bool {
// We do not use self.clicked(), because we want to catch all click within our frame, // We do not use self.clicked(), because we want to catch all clicks within our frame,
// even if we aren't clickable. This is important for windows and such that should close // even if we aren't clickable (or even enabled).
// then the user clicks elsewhere. // This is important for windows and such that should close then the user clicks elsewhere.
let pointer = &self.ctx.input().pointer; let pointer = &self.ctx.input().pointer;
if let Some(pos) = pointer.interact_pos() {
pointer.any_click() && !self.rect.contains(pos) if pointer.any_click() {
// We detect clicks/hover on a "interact_rect" that is slightly larger than
// self.rect. See Context::interact.
// This means we can be hovered and clicked even though `!self.rect.contains(pos)` is true,
// hence the extra complexity here.
if self.hovered() {
false
} else if let Some(pos) = pointer.interact_pos() {
!self.rect.contains(pos)
} else {
false // clicked without a pointer, weird
}
} else { } else {
false false
} }