From c3e84351701401d983bf256045e4a22c2b68c32b Mon Sep 17 00:00:00 2001 From: Jake Go Date: Wed, 14 Jan 2026 22:01:47 -0500 Subject: [PATCH 1/2] Dismiss context menus when window loses focus Context menus now close when the window becomes inactive (e.g., clicking to another window or app). Previously, menus would remain visible until the window regained focus. Uses `observe_window_activation` to detect when the window becomes inactive and calls `cancel` to dismiss the menu. --- crates/ui/src/components/context_menu.rs | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/ui/src/components/context_menu.rs b/crates/ui/src/components/context_menu.rs index 4372ebd821c9a9..66f7e6ea0f0ee7 100644 --- a/crates/ui/src/components/context_menu.rs +++ b/crates/ui/src/components/context_menu.rs @@ -220,6 +220,7 @@ pub struct ContextMenu { end_slot_action: Option>, key_context: SharedString, _on_blur_subscription: Subscription, + _on_window_deactivate_subscription: Subscription, keep_open_on_confirm: bool, fixed_width: Option, main_menu: Option>, @@ -295,6 +296,14 @@ 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 +318,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 +382,14 @@ 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 +404,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 +474,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 +1233,14 @@ 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 +1253,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, From 2f8a76718994674c02f7def3977a9812fa5a99f2 Mon Sep 17 00:00:00 2001 From: Danilo Leal Date: Thu, 15 Jan 2026 10:44:19 -0300 Subject: [PATCH 2/2] Format --- crates/ui/src/components/context_menu.rs | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/crates/ui/src/components/context_menu.rs b/crates/ui/src/components/context_menu.rs index 66f7e6ea0f0ee7..97f6624d1edcb2 100644 --- a/crates/ui/src/components/context_menu.rs +++ b/crates/ui/src/components/context_menu.rs @@ -296,14 +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| { + 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( @@ -382,14 +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| { + 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())( @@ -1233,14 +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| { + 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,