monaco-editor icon indicating copy to clipboard operation
monaco-editor copied to clipboard

[Bug] Paste does not work with Electron 34

Open dex4er opened this issue 9 months ago • 7 comments

Reproducible in vscode.dev or in VS Code Desktop?

  • [x] Not reproducible in vscode.dev or VS Code Desktop

Reproducible in the monaco editor playground?

Monaco Editor Playground Link

I see the Paste option in context menu. However it doesn't work. The same for ctrl-v or cmd-v.

Tested in application that uses Electron 34.3.3

After I added extra debug to the clipboard.js I see const result = focusedEditor.getContainerDomNode().ownerDocument.execCommand('paste'); returns false.

It is because actually this command doesn't work in Electron and probably import { clipboard } from "electron"; clipboard.readText() should be used instead.

Unfortunately, if result is false, the alternative code works only if (platform.isWeb) so not in Electron.

I think newer vscode has this logic fixed but 0.52.2 version stuck with older vscode.

Monaco Editor Playground Code


Reproduction Steps

No response

Actual (Problematic) Behavior

No response

Expected Behavior

No response

Additional Context

No response

dex4er avatar Mar 21 '25 21:03 dex4er

Nah, I think it was missing allow="clipboard-read; clipboard-write" for the iframe.

dex4er avatar Mar 22 '25 00:03 dex4er

This should not be closed, I think. I'm having this exact issue while trying to embed monaco-editor in Obsidian and there are no iframes involved at all, at least none that are user-controllable.

Unfortunately, if result is false, the alternative code works only if (platform.isWeb) so not in Electron.

This is correct, I've tried replacing it with if (true) and the modified version works as expected.

Mijyuoon avatar Mar 22 '25 10:03 Mijyuoon

I agree: it looks like wrong logic in the editor at the end. I had to remove if (platform.isWeb) too.

dex4er avatar Mar 22 '25 10:03 dex4er

My patch that I added using patch-package:

diff --git a/node_modules/monaco-editor/esm/vs/editor/contrib/clipboard/browser/clipboard.js b/node_modules/monaco-editor/esm/vs/editor/contrib/clipboard/browser/clipboard.js
index a1deb14..5598b9b 100644
--- a/node_modules/monaco-editor/esm/vs/editor/contrib/clipboard/browser/clipboard.js
+++ b/node_modules/monaco-editor/esm/vs/editor/contrib/clipboard/browser/clipboard.js
@@ -201,7 +201,7 @@ if (PasteAction) {
             if (result) {
                 return CopyPasteController.get(focusedEditor)?.finishedPaste() ?? Promise.resolve();
             }
-            else if (platform.isWeb) {
+            else /*if (platform.isWeb)*/ {
                 // Use the clipboard service if document.execCommand('paste') was not successful
                 return (async () => {
                     const clipboardText = await clipboardService.readText();

dex4er avatar Mar 22 '25 11:03 dex4er

Can we fix this please? This problem will happen if monaco editor is used with Electron.

To reiterate, it seems electron has dropped support for execCommand('paste') altogether (https://github.com/electron/electron/pull/45277), which was probably working till v33. The platform.isWeb condition isn't true for electron.

Happy to send a PR, but would like to understand better what the history is of platform.isWeb is and if it can be safely removed.

shubhamjain avatar Mar 26 '25 08:03 shubhamjain

Exteremely hacky fix for those who don't wish to use patch-package solution by @dex4er.

delete process.versions.node

Run this before monaco-editor gets included. Existence of this key used to determine if the process is Electron or not (https://github.com/xtermjs/xterm.js/blob/a260f7d2889142d6566a66cb9856a07050dea611/src/vs/base/common/platform.ts#L63). So deleting it fixes the issue.

shubhamjain avatar Mar 26 '25 08:03 shubhamjain

Same issue. I created this workaround in my app that fixes the problem until this is resolved:

import {app} from "electron";

const isMac = process.platform === "darwin";
app.on("browser-window-created", (_, win) => {
    win.webContents.on("before-input-event", (event, input) => {
        const isCmdOrCtrl = isMac ? input.meta === true : input.control === true;

        const hasShift =
            input.shift === true ||
            input.modifiers.includes("shift");

        const hasAlt =
            input.alt === true ||
            input.modifiers.includes("alt");

        // Prefer code (layout-agnostic)
        const isV = input.code === "KeyV" || input.key === "v";

        const shouldPaste =
            input.type === 'keyDown' &&
            isCmdOrCtrl &&
            !hasShift &&
            !hasAlt &&
            isV;

        if (shouldPaste) {
            // Native paste path (works with Monaco)
            win.webContents.paste();
            event.preventDefault();
        }
    });
});

tareqimbasher avatar Aug 13 '25 14:08 tareqimbasher