Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot paste content copied from outside on VS Code Web #200641

Closed
guiherzog opened this issue Dec 12, 2023 · 9 comments
Closed

Cannot paste content copied from outside on VS Code Web #200641

guiherzog opened this issue Dec 12, 2023 · 9 comments
Assignees
Labels
bug Issue identified by VS Code Team member as probable bug editor-clipboard Editor clipboard issues under-discussion Issue is under discussion for relevance, priority, approach verified Verification succeeded web Issues related to running VSCode in the web

Comments

@guiherzog
Copy link
Contributor

  • VS Code Version: Version: 1.85.0
    Commit: af28b32
    Date: 2023-12-06T18:18:26.691Z (5 days ago)
  • OS Version: Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

Steps to Reproduce:

  1. Open vscode.dev (or insiders).
  2. Copy a file with cmd/ctrl+c in the file explorer.
  3. Paste inside a document.
  4. It should paste the file path.
  5. Switch to another browser tab that is not vscode.dev and copy any text inside of it with cmd/ctrl+c.
  6. Switch back to vscode.dev.
  7. Paste the copied content inside an opened file in the editor.

Expected result:
The text copied outside of VS Code should be pasted there.

Current result:
It pastes the path of the file copied by step 2 in the file explorer.

This blocks me from using copy & paste properly until I reload VS Code completely.

@lramos15 lramos15 added bug Issue identified by VS Code Team member as probable bug editor-clipboard Editor clipboard issues labels Dec 12, 2023
@lramos15
Copy link
Member

@mjbvz Seems like we're not properly reading the right contents when pasting in the editor

  1. Copy a file
  2. Paste into notepad
  3. Nothing

  1. Copy a file
  2. Paste into editor, get paste options for which path type

  1. Copy a file
  2. Copy other text from a different source
  3. Paste into editor.
  4. Still the file path

  1. Copy a file
  2. Copy other text from a different source
  3. Paste into other application.
  4. The text in the clipboard is properly pasted

@mjbvz
Copy link
Collaborator

mjbvz commented Dec 13, 2023

Seems caused by the web clipboard being in-memory:

private resources: URI[] = []; // unsupported in web (only in-memory)

In the copy paste controller, I explicitly clear it to work around this:

// Explicitly clear the web resources clipboard.

However that won't work for external copies

@bpasero
Copy link
Member

bpasero commented Dec 13, 2023

This is tough to get right using web APIs where support for custom formats is very limited. Our solution is not very robust and thus leads to this issue.

I have played around for 10 minutes writing a different type into the clipboard for the writeResources / readResources method:

async writeResources(resources: URI[]): Promise<void> {
		try {
			return await navigator.clipboard.write([
				new ClipboardItem({
					['text/html']: new Blob([`<vscode>${resourcesToBuffer(resources).toString()}</vscode>`], { type: 'text/html' }),
				})
			]);
		} catch (error) {
			console.error(error);
		}

		// fallback to in-memory
		this.resources = resources;
	}

	async readResources(): Promise<URI[]> {
		try {
			const clipboardItems = await navigator.clipboard.read();
			for (const clipboardItem of clipboardItems) {
				for (const type of clipboardItem.types) {
					if (type !== 'text/html') {
						continue;
					}

					const blob = await clipboardItem.getType(type);
					console.log(await blob.text());

					// TODO convert back to URI if matching our format
				}
			}
		} catch (error) {
			console.error(error);
		}

		// fallback to in-memory
		return this.resources;
	}

One immediate issue is that text/uri-list for example is not a valid data type in Chrome. You can only use text/plain, text/html and image/png (according to https://stackoverflow.com/questions/68897154/list-of-supported-mime-types-for-clipboard-write).

We could maybe encode this into text/html and then try to decode it with a special format to see if it matches our format to implement this, but I am not sure if its worth it.

Maybe @deepak1556 for additional thoughts.

@bpasero bpasero added under-discussion Issue is under discussion for relevance, priority, approach web Issues related to running VSCode in the web labels Dec 13, 2023
@bpasero
Copy link
Member

bpasero commented Dec 13, 2023

I think this is actually quite a severe issue in web. Once you have resources in your clipboard, it seems to me you cannot paste anything else into the editor but that (!). So for example, these steps are much easier to reproduce:

  • copy in the explorer
  • decide to "Copy Path" from the explorer context menu
  • paste into editor
  • 🐛 the path is not pasted

One approach to solve this (see #200782) is to associate the resources with a state that is specific to the contents of the clipboard at that time with the goal to detect if that state has changed or not. Its ugly, because then writeResources already needs access to the clipboard, but I think the current behaviour is worse.

private async computeResourcesStateHash(): Promise<number | undefined> {
if (this.resources.length === 0) {
return undefined; // no resources, no hash needed
}
// Resources clipboard is managed in-memory only and thus
// fails to invalidate when clipboard data is changing.
// As such, we compute the hash of the current clipboard
// and use that to later validate the resources clipboard.
const clipboardText = await this.readText();
return hash(clipboardText.substring(0, BrowserClipboardService.MAX_RESOURCE_STATE_SOURCE_LENGTH));
}

bpasero added a commit that referenced this issue Dec 14, 2023
…00782)

* Cannot paste content copied from outside on VS Code Web (#200641)

* add a limit
@bpasero bpasero added this to the December / January 2024 milestone Dec 14, 2023
@bpasero bpasero closed this as completed Dec 14, 2023
@bpasero
Copy link
Member

bpasero commented Dec 14, 2023

I am also adding code to reset the resources when any copy event is detected in the document:

// Keep track of copy operations to reset our set of
// copied resources: since we keep resources in memory
// and not in the clipboard, we have to invalidate
// that state when the user copies other data.
this._register(Event.runAndSubscribe(onDidRegisterWindow, ({ window, disposables }) => {
disposables.add(addDisposableListener(window.document, 'copy', () => this.clearResources()));
}, { window: mainWindow, disposables: this._store }));

I believe that would make the code here obsolete:

this._clipboardService.writeResources([]);

@guiherzog
Copy link
Contributor Author

Thank you for the quick resolution!

@bpasero
Copy link
Member

bpasero commented Dec 19, 2023

This should work fine now from our insiders build if you want to verify: https://insiders.vscode.dev/

@guiherzog
Copy link
Contributor Author

It works for me, thanks!

@bpasero bpasero added the verified Verification succeeded label Dec 19, 2023
@bilogic
Copy link

bilogic commented Dec 23, 2023

Was this released into 1.85.1?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue identified by VS Code Team member as probable bug editor-clipboard Editor clipboard issues under-discussion Issue is under discussion for relevance, priority, approach verified Verification succeeded web Issues related to running VSCode in the web
Projects
None yet
Development

No branches or pull requests

6 participants