From 5f4d0dbaab48190ae17a173c614a2b9025bf4ba4 Mon Sep 17 00:00:00 2001 From: feeiyu <158308373+feeiyu@users.noreply.github.com> Date: Wed, 12 Nov 2025 01:20:38 +0800 Subject: [PATCH] Fix circular reference issue around PopoverMenu (#42461) Follow up to https://github.com/zed-industries/zed/pull/42351 Release Notes: - N/A --- .../src/edit_prediction_button.rs | 24 +++++++++++-------- crates/language_tools/src/lsp_button.rs | 9 +++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/crates/edit_prediction_button/src/edit_prediction_button.rs b/crates/edit_prediction_button/src/edit_prediction_button.rs index 6e9000bc62eea94d5c48dca2416781f46428522c..a0bbe18b4bcaaf433b15db333b3e5a7eb8dfb4d0 100644 --- a/crates/edit_prediction_button/src/edit_prediction_button.rs +++ b/crates/edit_prediction_button/src/edit_prediction_button.rs @@ -128,20 +128,21 @@ impl Render for EditPredictionButton { }), ); } - let this = cx.entity(); + let this = cx.weak_entity(); div().child( PopoverMenu::new("copilot") .menu(move |window, cx| { let current_status = Copilot::global(cx)?.read(cx).status(); - Some(match current_status { + match current_status { Status::Authorized => this.update(cx, |this, cx| { this.build_copilot_context_menu(window, cx) }), _ => this.update(cx, |this, cx| { this.build_copilot_start_menu(window, cx) }), - }) + } + .ok() }) .anchor(Corner::BottomRight) .trigger_with_tooltip( @@ -182,7 +183,7 @@ impl Render for EditPredictionButton { let icon = status.to_icon(); let tooltip_text = status.to_tooltip(); let has_menu = status.has_menu(); - let this = cx.entity(); + let this = cx.weak_entity(); let fs = self.fs.clone(); div().child( @@ -209,9 +210,11 @@ impl Render for EditPredictionButton { ) })) } - SupermavenButtonStatus::Ready => Some(this.update(cx, |this, cx| { - this.build_supermaven_context_menu(window, cx) - })), + SupermavenButtonStatus::Ready => this + .update(cx, |this, cx| { + this.build_supermaven_context_menu(window, cx) + }) + .ok(), _ => None, }) .anchor(Corner::BottomRight) @@ -233,15 +236,16 @@ impl Render for EditPredictionButton { let enabled = self.editor_enabled.unwrap_or(true); let has_api_key = CodestralCompletionProvider::has_api_key(cx); let fs = self.fs.clone(); - let this = cx.entity(); + let this = cx.weak_entity(); div().child( PopoverMenu::new("codestral") .menu(move |window, cx| { if has_api_key { - Some(this.update(cx, |this, cx| { + this.update(cx, |this, cx| { this.build_codestral_context_menu(window, cx) - })) + }) + .ok() } else { Some(ContextMenu::build(window, cx, |menu, _, _| { let fs = fs.clone(); diff --git a/crates/language_tools/src/lsp_button.rs b/crates/language_tools/src/lsp_button.rs index 7dc2e93a5c707eaa3829caba6d6d2a04773883b1..ee49114b787e764989453fae1d12f61253eea099 100644 --- a/crates/language_tools/src/lsp_button.rs +++ b/crates/language_tools/src/lsp_button.rs @@ -1053,11 +1053,16 @@ impl Render for LspButton { (None, "All Servers Operational") }; - let lsp_button = cx.entity(); + let lsp_button = cx.weak_entity(); div().child( PopoverMenu::new("lsp-tool") - .menu(move |_, cx| lsp_button.read(cx).lsp_menu.clone()) + .menu(move |_, cx| { + lsp_button + .read_with(cx, |lsp_button, _| lsp_button.lsp_menu.clone()) + .ok() + .flatten() + }) .anchor(Corner::BottomLeft) .with_handle(self.popover_menu_handle.clone()) .trigger_with_tooltip(