acp: Cancel editing when focus is lost and message was not changed (#36822)

Release Notes:

- N/A
This commit is contained in:
Bennet Bo Fenner 2025-08-24 13:05:39 +02:00 committed by Joseph T. Lyons
parent 29120ad573
commit 3b4c891242
3 changed files with 24 additions and 7 deletions

View file

@ -509,7 +509,7 @@ impl ContentBlock {
"`Image`".into()
}
fn to_markdown<'a>(&'a self, cx: &'a App) -> &'a str {
pub fn to_markdown<'a>(&'a self, cx: &'a App) -> &'a str {
match self {
ContentBlock::Empty => "",
ContentBlock::Markdown { markdown } => markdown.read(cx).source(),

View file

@ -74,6 +74,7 @@ pub enum MessageEditorEvent {
Send,
Cancel,
Focus,
LostFocus,
}
impl EventEmitter<MessageEditorEvent> for MessageEditor {}
@ -131,10 +132,14 @@ impl MessageEditor {
editor
});
cx.on_focus(&editor.focus_handle(cx), window, |_, _, cx| {
cx.on_focus_in(&editor.focus_handle(cx), window, |_, _, cx| {
cx.emit(MessageEditorEvent::Focus)
})
.detach();
cx.on_focus_out(&editor.focus_handle(cx), window, |_, _, _, cx| {
cx.emit(MessageEditorEvent::LostFocus)
})
.detach();
let mut subscriptions = Vec::new();
subscriptions.push(cx.subscribe_in(&editor, window, {
@ -1169,17 +1174,16 @@ impl MessageEditor {
})
}
pub fn text(&self, cx: &App) -> String {
self.editor.read(cx).text(cx)
}
#[cfg(test)]
pub fn set_text(&mut self, text: &str, window: &mut Window, cx: &mut Context<Self>) {
self.editor.update(cx, |editor, cx| {
editor.set_text(text, window, cx);
});
}
#[cfg(test)]
pub fn text(&self, cx: &App) -> String {
self.editor.read(cx).text(cx)
}
}
fn render_directory_contents(entries: Vec<(Arc<Path>, PathBuf, String)>) -> String {

View file

@ -762,6 +762,7 @@ impl AcpThreadView {
MessageEditorEvent::Focus => {
self.cancel_editing(&Default::default(), window, cx);
}
MessageEditorEvent::LostFocus => {}
}
}
@ -793,6 +794,18 @@ impl AcpThreadView {
cx.notify();
}
}
ViewEvent::MessageEditorEvent(editor, MessageEditorEvent::LostFocus) => {
if let Some(thread) = self.thread()
&& let Some(AgentThreadEntry::UserMessage(user_message)) =
thread.read(cx).entries().get(event.entry_index)
&& user_message.id.is_some()
{
if editor.read(cx).text(cx).as_str() == user_message.content.to_markdown(cx) {
self.editing_message = None;
cx.notify();
}
}
}
ViewEvent::MessageEditorEvent(editor, MessageEditorEvent::Send) => {
self.regenerate(event.entry_index, editor, window, cx);
}