From 0af7d32b7decd0da3729f1c48f2813438ca6de05 Mon Sep 17 00:00:00 2001 From: Finn Evers Date: Sun, 13 Jul 2025 23:41:41 +0200 Subject: [PATCH] keymap_ui: Dismiss context menu less frequently (#34387) This PR fixes an issue where the context menu in the keymap UI would be immediately dismissed after being opened when using a trackpad on MacOS. Right clicking on MacOS almost always fires a scroll event with a delta of 0 pixels right after (which is not the case when using a mouse). The fired scroll event caused the context menu to be removed on the next frame. This change ensures the menu is only removed when a vertical scroll is actually happening. Release Notes: - N/A --- crates/settings_ui/src/keybindings.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/settings_ui/src/keybindings.rs b/crates/settings_ui/src/keybindings.rs index c78a370f12..210ec827cc 100644 --- a/crates/settings_ui/src/keybindings.rs +++ b/crates/settings_ui/src/keybindings.rs @@ -11,9 +11,9 @@ use fs::Fs; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ Action, AnimationExt, AppContext as _, AsyncApp, ClickEvent, Context, DismissEvent, Entity, - EventEmitter, FocusHandle, Focusable, Global, KeyContext, KeyDownEvent, Keystroke, - ModifiersChangedEvent, MouseButton, Point, ScrollStrategy, StyledText, Subscription, - WeakEntity, actions, anchored, deferred, div, + EventEmitter, FocusHandle, Focusable, Global, IsZero, KeyContext, KeyDownEvent, Keystroke, + ModifiersChangedEvent, MouseButton, Point, ScrollStrategy, ScrollWheelEvent, StyledText, + Subscription, WeakEntity, actions, anchored, deferred, div, }; use language::{Language, LanguageConfig, ToOffset as _}; use settings::{BaseKeymap, KeybindSource, KeymapFile, SettingsAssets}; @@ -1182,9 +1182,13 @@ impl Render for KeymapEditor { }), ), ) - .on_scroll_wheel(cx.listener(|this, _, _, cx| { - this.context_menu.take(); - cx.notify(); + .on_scroll_wheel(cx.listener(|this, event: &ScrollWheelEvent, _, cx| { + // This ensures that the menu is not dismissed in cases where scroll events + // with a delta of zero are emitted + if !event.delta.pixel_delta(px(1.)).y.is_zero() { + this.context_menu.take(); + cx.notify(); + } })) .children(self.context_menu.as_ref().map(|(menu, position, _)| { deferred(