diff --git a/shell/browser/ui/inspectable_web_contents.cc b/shell/browser/ui/inspectable_web_contents.cc index f05476527b..50abf0fe4d 100644 --- a/shell/browser/ui/inspectable_web_contents.cc +++ b/shell/browser/ui/inspectable_web_contents.cc @@ -519,6 +519,12 @@ void InspectableWebContents::UpdateDevToolsZoomLevel(double level) { } void InspectableWebContents::ActivateWindow() { + if (embedder_message_dispatcher_) { + if (managed_devtools_web_contents_ && view_) { + view_->ActivateDevTools(); + } + } + // Set the zoom level. SetZoomLevelForWebContents(GetDevToolsWebContents(), GetDevToolsZoomLevel()); } diff --git a/shell/browser/ui/inspectable_web_contents_view.cc b/shell/browser/ui/inspectable_web_contents_view.cc index a71f544aae..88432df143 100644 --- a/shell/browser/ui/inspectable_web_contents_view.cc +++ b/shell/browser/ui/inspectable_web_contents_view.cc @@ -132,6 +132,23 @@ void InspectableWebContentsView::ShowDevTools(bool activate) { } } +void InspectableWebContentsView::ActivateDevTools() { + if (!devtools_visible_) { + return; + } + if (devtools_window_) { + if (!devtools_window_->IsActive()) { + devtools_window_->Activate(); + } + return; + } + if (devtools_web_view_) { + if (!devtools_web_view_->HasFocus()) { + devtools_web_view_->RequestFocus(); + } + } +} + void InspectableWebContentsView::CloseDevTools() { if (!devtools_visible_) return; diff --git a/shell/browser/ui/inspectable_web_contents_view.h b/shell/browser/ui/inspectable_web_contents_view.h index 282d3bf805..9fe35e4c44 100644 --- a/shell/browser/ui/inspectable_web_contents_view.h +++ b/shell/browser/ui/inspectable_web_contents_view.h @@ -49,6 +49,7 @@ class InspectableWebContentsView : public views::View { void SetCornerRadii(const gfx::RoundedCornersF& corner_radii); void ShowDevTools(bool activate); + void ActivateDevTools(); void CloseDevTools(); bool IsDevToolsViewShowing(); bool IsDevToolsViewFocused(); diff --git a/spec/api-web-contents-spec.ts b/spec/api-web-contents-spec.ts index fc4b3314fb..2005409364 100644 --- a/spec/api-web-contents-spec.ts +++ b/spec/api-web-contents-spec.ts @@ -1,6 +1,6 @@ import { BrowserWindow, ipcMain, webContents, session, app, BrowserView, WebContents, BaseWindow, WebContentsView } from 'electron/main'; -import { expect } from 'chai'; +import { assert, expect } from 'chai'; import * as cp from 'node:child_process'; import { once } from 'node:events'; @@ -995,6 +995,41 @@ describe('webContents module', () => { await devToolsClosed; expect(() => { webContents.getFocusedWebContents(); }).to.not.throw(); }); + + it('Inspect activates detached devtools window', async () => { + const window = new BrowserWindow({ show: true }); + await window.loadURL('about:blank'); + const webContentsBeforeOpenedDevtools = webContents.getAllWebContents(); + + const windowWasBlurred = once(window, 'blur'); + window.webContents.openDevTools({ mode: 'detach' }); + await windowWasBlurred; + + let devToolsWebContents = null; + for (const newWebContents of webContents.getAllWebContents()) { + const oldWebContents = webContentsBeforeOpenedDevtools.find( + oldWebContents => { + return newWebContents.id === oldWebContents.id; + }); + if (oldWebContents !== null) { + devToolsWebContents = newWebContents; + break; + } + } + assert(devToolsWebContents !== null); + + const windowFocused = once(window, 'focus'); + window.focus(); + await windowFocused; + + expect(devToolsWebContents.isFocused()).to.be.false(); + const devToolsWebContentsFocused = once(devToolsWebContents, 'focus'); + window.webContents.inspectElement(100, 100); + await devToolsWebContentsFocused; + + expect(devToolsWebContents.isFocused()).to.be.true(); + expect(window.isFocused()).to.be.false(); + }); }); describe('setDevToolsWebContents() API', () => {