ElyMark: R4.10 round 2 fixes (copy guard, component 2b8bd9f)

A pending conversion no longer overwrites a later clipboard write; pin
moves to component 2b8bd9f (one-pass drawn lookup, latest press wins).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-14 21:52:25 -04:00
1 parent 67fa5bfc94
commit 2c374b23ed
8 files changed
+49 -7

No files matched your search

+31 -1
View File
@@ -168,12 +168,42 @@ fn copies_convert_off_the_window_thread(cx: &mut TestAppContext) {
cx.write_to_clipboard(gpui::ClipboardItem::new_string("before".into()));
// The context's dispatch parks; this one does not.
cx.update(|window, cx| window.dispatch_action(Box::new(crate::export::CopyHtml), cx));
assert_eq!(clipboard(cx).as_deref(), Some("before"), "not on the window thread");
assert_eq!(
clipboard(cx).as_deref(),
Some("before"),
"not on the window thread"
);
cx.update(|window, cx| window.dispatch_action(Box::new(crate::export::CopyPlain), cx));
cx.run_until_parked();
assert_eq!(clipboard(cx).as_deref(), Some("alpha it\n"));
}
#[gpui::test]
fn a_later_markdown_copy_outlives_a_pending_conversion(cx: &mut TestAppContext) {
let (_desk, cx, _files) = opened("alpha *it*\n", cx);
cx.update(|window, cx| window.dispatch_action(Box::new(crate::export::CopyHtml), cx));
cx.update(|window, cx| window.dispatch_action(Box::new(crate::clip::CopyMarkdown), cx));
cx.run_until_parked();
assert_eq!(clipboard(cx).as_deref(), Some("alpha *it*\n"));
}
#[gpui::test]
fn a_later_editor_copy_outlives_a_pending_conversion(cx: &mut TestAppContext) {
use gpui::Focusable as _;
let (desk, cx, _files) = opened("alpha *it*\n", cx);
switch(&desk, Mode::Source, cx);
let editor = document(&desk, cx).read_with(cx, |document, _| document.editor().clone());
editor.update(cx, |editor, cx| editor.select(std::iter::once(0..5), cx));
let focus = editor.read_with(cx, |editor, cx| editor.focus_handle(cx));
cx.update(|window, cx| window.focus(&focus, cx));
cx.run_until_parked();
cx.update(|window, cx| window.dispatch_action(Box::new(crate::export::CopyHtml), cx));
let copy = gpui::Keystroke::parse("secondary-c").expect("key");
cx.update(|window, cx| window.dispatch_keystroke(copy, cx));
cx.run_until_parked();
assert_eq!(clipboard(cx).as_deref(), Some("alpha"));
}
#[gpui::test]
fn a_shut_menu_stays_shut_when_its_tab_returns(cx: &mut TestAppContext) {
let (desk, cx, files) = opened("alpha\n", cx);
+5
View File
@@ -64,6 +64,7 @@ impl Desk {
let Some((markdown, beside)) = self.copied_text(cx) else {
return;
};
let before = cx.read_from_clipboard();
self.copying = Some(cx.spawn(async move |desk, cx| {
let converted = cx
.background_executor()
@@ -71,6 +72,10 @@ impl Desk {
.await;
let landed = desk.update(cx, |desk, cx| {
desk.copying = None;
// A later copy, here or elsewhere, wins.
if cx.read_from_clipboard() != before {
return log::info!("mark: the clipboard changed first; a copy is dropped");
}
desk.copied(converted, cx);
});
if landed.is_err() {