agent_ui: Disable "Copy Selection" when no text is selected (#47997)

Xiaobo Liu created

Release Notes:

- Agent: Improved the "Copy Selection" right-click menu item by
disabling it when there are no selections.

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>

Change summary

crates/agent_ui/src/acp/thread_view.rs | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

Detailed changes

crates/agent_ui/src/acp/thread_view.rs 🔗

@@ -2536,12 +2536,28 @@ impl AcpThreadView {
                 let workspace = workspace.clone();
 
                 ContextMenu::build(window, cx, move |menu, _, cx| {
-                    let is_at_top = entity
-                        .read(cx)
-                        .as_active_thread()
+                    let active_thread = entity.read(cx).as_active_thread();
+                    let is_at_top = active_thread
                         .map(|active| &active.list_state)
                         .map_or(true, |state| state.logical_scroll_top().item_ix == 0);
 
+                    let has_selection = active_thread
+                        .and_then(|active| active.thread.read(cx).entries().get(entry_ix))
+                        .and_then(|entry| match entry {
+                            AgentThreadEntry::AssistantMessage(msg) => Some(&msg.chunks),
+                            _ => None,
+                        })
+                        .map(|chunks| {
+                            chunks.iter().any(|chunk| {
+                                let md = match chunk {
+                                    AssistantMessageChunk::Message { block } => block.markdown(),
+                                    AssistantMessageChunk::Thought { block } => block.markdown(),
+                                };
+                                md.map_or(false, |m| m.read(cx).selected_text().is_some())
+                            })
+                        })
+                        .unwrap_or(false);
+
                     let copy_this_agent_response =
                         ContextMenuEntry::new("Copy This Agent Response").handler({
                             let entity = entity.clone();
@@ -2595,7 +2611,11 @@ impl AcpThreadView {
                         });
 
                     menu.when_some(focus, |menu, focus| menu.context(focus))
-                        .action("Copy Selection", Box::new(markdown::CopyAsMarkdown))
+                        .action_disabled_when(
+                            !has_selection,
+                            "Copy Selection",
+                            Box::new(markdown::CopyAsMarkdown),
+                        )
                         .item(copy_this_agent_response)
                         .separator()
                         .item(scroll_item)