fix: make yank-to-system-clipboard work when the document isn't focused#287
Open
beenerdy wants to merge 1 commit into
Open
fix: make yank-to-system-clipboard work when the document isn't focused#287beenerdy wants to merge 1 commit into
beenerdy wants to merge 1 commit into
Conversation
`navigator.clipboard.writeText` rejects with "Document is not focused" during focus changes, so with `set clipboard=unnamed` a yank silently never reaches the system clipboard and the setting appears to stop working (intermittently). The clipboard->yank read path already guards against this exact error, but the yank->clipboard write path did not, and an unhandled rejection also dropped the state update. Prefer Electron's synchronous, focus-independent clipboard on the desktop app, falling back to the async API where `require` is unavailable (e.g. mobile). On any failure, leave `lastYankBuffer` unchanged so a later keyup/click/focusin event retries the write. Refs esm7#276
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
With
set clipboard=unnamed(orunnamedplus), yanking sometimes fails to reach the system clipboard, even though the console logsVim is now set to yank to system clipboard.andyankToSystemClipboardistrue. It works most of the time, then intermittently stops until the editor is interacted with again. Reported in #276.Root cause
captureYankBufferbridges the vimyankregister to the system clipboard and is fired fromkeyup,click, andfocusindocument handlers. Its two directions were asymmetric:try/catchspecifically to swallowDOMException: Document is not focused(the existingXXXcomment).await win.navigator.clipboard.writeText(buf)unguarded.The async Clipboard API only resolves when the document is focused. During any focus change (window blur, a popover/palette stealing focus, or the
focusinhandler firing beforedocument.hasFocus()is true), the write rejects. The yank is silently dropped,this.lastYankBufferis not advanced, and the rejection is unhandled. Because nativeCmd/Ctrl+Cuses a different, synchronous path, users see "only vim yank is broken, and only sometimes." This is not platform-specific: the focus gating is Chromium behavior, so it reproduces on macOS, Windows (#276), and Linux.Fix
In the write branch, prefer Electron's clipboard, which is synchronous and focus-independent (the same reliability class as native copy), and fall back to
navigator.clipboard.writeTextwhererequireis unavailable (e.g. mobile):The whole branch is wrapped in
try/catch; on failurelastYankBufferis left unchanged so the nextkeyup/click/focusinretries.lastSystemClipboardis set to the value just written instead of via a second focus-gatedreadText().Mobile behavior is unchanged (falls through to the async API).
requireis accessed as(win as any).requireto avoid a barerequireundernoImplicitAnyand to keep the commonjs plugin from resolvingelectronat build time.Testing
npm run buildsucceeds (the only diagnostics are the pre-existingvim-command-donetyping warnings, unrelated to this change).npx vitest runpasses (62/62).blurevent that made the old async path reject.