From d753c50088d2c492af678cb8aa68bb3ce3187819 Mon Sep 17 00:00:00 2001 From: Moti Zilberman Date: Mon, 2 Jun 2025 11:31:53 -0700 Subject: [PATCH] Bring RNDT shell to front when paused on breakpoint Summary: Changelog: [Internal] Implements the first RNDT shell-specific feature based on https://github.com/facebook/react-native-devtools-frontend/pull/168 - namely, the ability for RNDT to foreground itself when certain events occur. This is most noticeable when pausing on a breakpoint. Differential Revision: D75795689 --- .../src/electron/MainInstanceEntryPoint.js | 16 +++++++- .../debugger-shell/src/electron/preload.js | 41 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 packages/debugger-shell/src/electron/preload.js diff --git a/packages/debugger-shell/src/electron/MainInstanceEntryPoint.js b/packages/debugger-shell/src/electron/MainInstanceEntryPoint.js index dcbecc8db3f3..9fe927e2ff20 100644 --- a/packages/debugger-shell/src/electron/MainInstanceEntryPoint.js +++ b/packages/debugger-shell/src/electron/MainInstanceEntryPoint.js @@ -9,7 +9,7 @@ */ // $FlowFixMe[unclear-type] We have no Flow types for the Electron API. -const {BrowserWindow, app, shell} = require('electron') as any; +const {BrowserWindow, app, shell, ipcMain} = require('electron') as any; const util = require('util'); const windowMetadata = new WeakMap< @@ -66,6 +66,7 @@ function handleLaunchArgs(argv: string[]) { height: 600, webPreferences: { partition: 'persist:react-native-devtools', + preload: require.resolve('./preload.js'), }, }); @@ -102,3 +103,16 @@ app.whenReady().then(() => { app.on('window-all-closed', function () { app.quit(); }); + +ipcMain.on('bringToFront', (event, title) => { + const webContents = event.sender; + const win = BrowserWindow.fromWebContents(webContents); + if (win) { + win.focus(); + } + if (process.platform === 'darwin') { + app.focus({ + steal: true, + }); + } +}); diff --git a/packages/debugger-shell/src/electron/preload.js b/packages/debugger-shell/src/electron/preload.js new file mode 100644 index 000000000000..22c4e0bbff8f --- /dev/null +++ b/packages/debugger-shell/src/electron/preload.js @@ -0,0 +1,41 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +const {contextBridge, ipcRenderer} = require('electron'); + +contextBridge.executeInMainWorld({ + func: ipcDevTools => { + let didDecorateInspectorFrontendHostInstance = false; + // reactNativeDecorateInspectorFrontendHostInstance was introduced in + // https://github.com/facebook/react-native-devtools-frontend/pull/168 + globalThis.reactNativeDecorateInspectorFrontendHostInstance = + InspectorFrontendHostInstance => { + didDecorateInspectorFrontendHostInstance = true; + InspectorFrontendHostInstance.bringToFront = () => { + ipcDevTools.bringToFront(); + }; + }; + + document.addEventListener('DOMContentLoaded', () => { + if (!didDecorateInspectorFrontendHostInstance) { + console.error( + 'reactNativeDecorateInspectorFrontendHostInstance was not called at startup. ' + + 'This version of the DevTools frontend may not be compatible with @react-native/debugger-shell.', + ); + } + }); + }, + args: [ + { + bringToFront() { + ipcRenderer.send('bringToFront'); + }, + }, + ], +});