ui: Dismiss context menus when window loses focus (#46866)
Context menus close when the window becomes inactive (e.g., clicking to another window or app). Previously, menus would remain visible until the window regained focus. This aligns Zed's context menu behavior with native macOS apps, where NSMenu automatically dismisses when the window loses focus. Users expect menus to close when switching windows or apps. Uses `observe_window_activation` to detect when the window becomes inactive and calls `cancel` to dismiss the menu. Release Notes: - Fixed context menus dismiss/cancel when the window loses focus --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
This commit is contained in:
1 parent
b8bbe163fc
commit
955e8983d1
1 file changed
+30
@@ -220,6 +220,7 @@ pub struct ContextMenu {
|
||||
end_slot_action: Option<Box<dyn Action>>,
|
||||
key_context: SharedString,
|
||||
_on_blur_subscription: Subscription,
|
||||
_on_window_deactivate_subscription: Subscription,
|
||||
keep_open_on_confirm: bool,
|
||||
fixed_width: Option<DefiniteLength>,
|
||||
main_menu: Option<Entity<ContextMenu>>,
|
||||
@@ -295,6 +296,12 @@ impl ContextMenu {
|
||||
this.cancel(&menu::Cancel, window, cx)
|
||||
},
|
||||
);
|
||||
let _on_window_deactivate_subscription =
|
||||
cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
|
||||
if !window.is_window_active() {
|
||||
this.cancel(&menu::Cancel, window, cx);
|
||||
}
|
||||
});
|
||||
window.refresh();
|
||||
|
||||
f(
|
||||
@@ -309,6 +316,7 @@ impl ContextMenu {
|
||||
end_slot_action: None,
|
||||
key_context: "menu".into(),
|
||||
_on_blur_subscription,
|
||||
_on_window_deactivate_subscription,
|
||||
keep_open_on_confirm: false,
|
||||
fixed_width: None,
|
||||
main_menu: None,
|
||||
@@ -372,6 +380,12 @@ impl ContextMenu {
|
||||
this.cancel(&menu::Cancel, window, cx)
|
||||
},
|
||||
);
|
||||
let _on_window_deactivate_subscription =
|
||||
cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
|
||||
if !window.is_window_active() {
|
||||
this.cancel(&menu::Cancel, window, cx);
|
||||
}
|
||||
});
|
||||
window.refresh();
|
||||
|
||||
(builder.clone())(
|
||||
@@ -386,6 +400,7 @@ impl ContextMenu {
|
||||
end_slot_action: None,
|
||||
key_context: "menu".into(),
|
||||
_on_blur_subscription,
|
||||
_on_window_deactivate_subscription,
|
||||
keep_open_on_confirm: true,
|
||||
fixed_width: None,
|
||||
main_menu: None,
|
||||
@@ -455,6 +470,14 @@ impl ContextMenu {
|
||||
this.cancel(&menu::Cancel, window, cx)
|
||||
},
|
||||
),
|
||||
_on_window_deactivate_subscription: cx.observe_window_activation(
|
||||
window,
|
||||
|this: &mut ContextMenu, window, cx| {
|
||||
if !window.is_window_active() {
|
||||
this.cancel(&menu::Cancel, window, cx);
|
||||
}
|
||||
},
|
||||
),
|
||||
keep_open_on_confirm: false,
|
||||
fixed_width: None,
|
||||
main_menu: None,
|
||||
@@ -1206,6 +1229,12 @@ impl ContextMenu {
|
||||
window,
|
||||
|_this: &mut ContextMenu, _window, _cx| {},
|
||||
);
|
||||
let _on_window_deactivate_subscription =
|
||||
cx.observe_window_activation(window, |this: &mut ContextMenu, window, cx| {
|
||||
if !window.is_window_active() {
|
||||
this.cancel(&menu::Cancel, window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
let mut menu = ContextMenu {
|
||||
builder: None,
|
||||
@@ -1218,6 +1247,7 @@ impl ContextMenu {
|
||||
end_slot_action: None,
|
||||
key_context: "menu".into(),
|
||||
_on_blur_subscription,
|
||||
_on_window_deactivate_subscription,
|
||||
keep_open_on_confirm: false,
|
||||
fixed_width: None,
|
||||
documentation_aside: None,
|
||||
|
||||
Reference in new issue
Block a user