Repository navigation
Conversation
A ClipboardItem from navigator.clipboard.read() reads the system clipboard when getType() is called, and Chrome throws "InvalidStateError: Clipboard data has changed" if it changed after read(). Clicking into the session after focusing the tab reads the local clipboard; anything that copies in that window (selecting text in the session, which the server sends straight back as a clipboard write, a clipboard manager, a copy on the client) made getType() throw. Nothing caught it, so it reached the noVNC error overlay, the local clipboard wasn't sent, and if the first type had been read its hash was kept, so the same copy was skipped as "No clipboard changes" afterwards. Wait for our own clipboard write to finish before reading, read once more if the clipboard changes anyway, and failing that try again on the next user-driven event. Record the hash only once the clipboard is sent.
|
I've applied this fix and confirmed that it resolves Chrome's |
|
I've tried applying this fix on top of |
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.
Every so often, clicking into a session shows the noVNC error overlay:
It happens on stock workspaces too.
Cause. With binary clipboard on, the first user-driven event after the tab regains focus calls
checkLocalClipboard(), which runsnavigator.clipboard.read()and passes the items toclipboardPasteDataFrom(). In Chrome aClipboardItemdoesn't hold the data:getType()reads the system clipboard when it is called, and throwsInvalidStateErrorif the clipboard changed afterread(). The loop awaitsgetType()andarrayBuffer()once per type, so anything that copies in between makes it throw:_write_binary_clipboard()writes the clipboard mid-readThe rejection from the async
clipboardPasteDataFrom()isn't caught (the.then(ok, err)only coversread()), soapp/error-handler.jsshows it. There are two side effects:_resendClipboardNextUserDrivenEventwas already cleared_clipHashkeeps its hash, so copying the same thing again is skipped as "No clipboard changes"Fix (
core/rfb.js):_sendLocalClipboard()waits for an in-flight_write_binary_clipboard()before reading. IfInvalidStateErrorhappens anyway, it callsread()once more. If that also fails, it sets_resendClipboardNextUserDrivenEventagain so the next click retries, and the rejection is caught and logged at debug level._clipHashis set only once every type has been read and the clipboard is sent._write_binary_clipboard()keeps its promise in_clipboardWrite. ItswriteTextfallback is now returned, so that promise covers the fallback too.Tested by loading
core/rfb.jsin Node with a mockednavigator.clipboardwhosegetType()throws like Chrome's once the clipboard has changed:InvalidStateError, nothing sent, and the resend flag left cleared.Linting
core/rfb.jsgives the same results before and after.