From d63a84801120215308b4a49271e9b69418de0716 Mon Sep 17 00:00:00 2001 From: Milan Burda Date: Tue, 27 Nov 2018 10:34:44 +0100 Subject: [PATCH] feat: add activate option to webContents.openDevTools (#13852) --- atom/browser/api/atom_api_web_contents.cc | 4 +++- .../cocoa/atom_inspectable_web_contents_view.h | 4 ++-- .../cocoa/atom_inspectable_web_contents_view.mm | 16 ++++++++++------ atom/browser/ui/inspectable_web_contents.h | 2 +- atom/browser/ui/inspectable_web_contents_impl.cc | 10 ++++++---- atom/browser/ui/inspectable_web_contents_impl.h | 3 ++- atom/browser/ui/inspectable_web_contents_view.h | 4 ++-- .../ui/inspectable_web_contents_view_mac.h | 4 ++-- .../ui/inspectable_web_contents_view_mac.mm | 10 +++++----- .../views/inspectable_web_contents_view_views.cc | 12 ++++++++---- .../views/inspectable_web_contents_view_views.h | 4 ++-- docs/api/web-contents.md | 6 ++++-- spec/api-web-contents-spec.js | 16 ++++++++++++++++ 13 files changed, 63 insertions(+), 32 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 24d8c0569afff..c62ee55bc7476 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1307,14 +1307,16 @@ void WebContents::OpenDevTools(mate::Arguments* args) { if (type_ == WEB_VIEW || !owner_window()) { state = "detach"; } + bool activate = true; if (args && args->Length() == 1) { mate::Dictionary options; if (args->GetNext(&options)) { options.Get("mode", &state); + options.Get("activate", &activate); } } managed_web_contents()->SetDockState(state); - managed_web_contents()->ShowDevTools(); + managed_web_contents()->ShowDevTools(activate); } void WebContents::CloseDevTools() { diff --git a/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h b/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h index c2db85cad0a2d..358f83fe75cfa 100644 --- a/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h +++ b/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.h @@ -34,10 +34,10 @@ using atom::InspectableWebContentsViewMac; (InspectableWebContentsViewMac*)view; - (void)removeObservers; - (void)notifyDevToolsFocused; -- (void)setDevToolsVisible:(BOOL)visible; +- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate; - (BOOL)isDevToolsVisible; - (BOOL)isDevToolsFocused; -- (void)setIsDocked:(BOOL)docked; +- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate; - (void)setContentsResizingStrategy: (const DevToolsContentsResizingStrategy&)strategy; - (void)setTitle:(NSString*)title; diff --git a/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm b/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm index 49e42fcc6e63b..69e83db80c0dc 100644 --- a/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm +++ b/atom/browser/ui/cocoa/atom_inspectable_web_contents_view.mm @@ -63,7 +63,7 @@ - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { } - (IBAction)showDevTools:(id)sender { - inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools(); + inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools(true); } - (void)notifyDevToolsFocused { @@ -71,7 +71,7 @@ - (void)notifyDevToolsFocused { inspectableWebContentsView_->GetDelegate()->DevToolsFocused(); } -- (void)setDevToolsVisible:(BOOL)visible { +- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { if (visible == devtools_visible_) return; @@ -106,7 +106,11 @@ - (void)setDevToolsVisible:(BOOL)visible { } } else { if (visible) { - [devtools_window_ makeKeyAndOrderFront:nil]; + if (activate) { + [devtools_window_ makeKeyAndOrderFront:nil]; + } else { + [devtools_window_ orderBack:nil]; + } } else { [devtools_window_ setDelegate:nil]; [devtools_window_ close]; @@ -127,9 +131,9 @@ - (BOOL)isDevToolsFocused { } } -- (void)setIsDocked:(BOOL)docked { +- (void)setIsDocked:(BOOL)docked activate:(BOOL)activate { // Revert to no-devtools state. - [self setDevToolsVisible:NO]; + [self setDevToolsVisible:NO activate:NO]; // Switch to new state. devtools_docked_ = docked; @@ -163,7 +167,7 @@ - (void)setIsDocked:(BOOL)docked { [contentView addSubview:devToolsView]; } - [self setDevToolsVisible:YES]; + [self setDevToolsVisible:YES activate:activate]; } - (void)setContentsResizingStrategy: diff --git a/atom/browser/ui/inspectable_web_contents.h b/atom/browser/ui/inspectable_web_contents.h index 3835baa046861..fe4c2c3bd0d7b 100644 --- a/atom/browser/ui/inspectable_web_contents.h +++ b/atom/browser/ui/inspectable_web_contents.h @@ -47,7 +47,7 @@ class InspectableWebContents { virtual void ReleaseWebContents() = 0; virtual void SetDevToolsWebContents(content::WebContents* devtools) = 0; virtual void SetDockState(const std::string& state) = 0; - virtual void ShowDevTools() = 0; + virtual void ShowDevTools(bool activate) = 0; virtual void CloseDevTools() = 0; virtual bool IsDevToolsViewShowing() = 0; virtual void AttachTo(scoped_refptr) = 0; diff --git a/atom/browser/ui/inspectable_web_contents_impl.cc b/atom/browser/ui/inspectable_web_contents_impl.cc index b1cc4563b3d32..d41c4f286ecf3 100644 --- a/atom/browser/ui/inspectable_web_contents_impl.cc +++ b/atom/browser/ui/inspectable_web_contents_impl.cc @@ -306,13 +306,15 @@ void InspectableWebContentsImpl::SetDevToolsWebContents( external_devtools_web_contents_ = devtools; } -void InspectableWebContentsImpl::ShowDevTools() { +void InspectableWebContentsImpl::ShowDevTools(bool activate) { if (embedder_message_dispatcher_) { if (managed_devtools_web_contents_) - view_->ShowDevTools(); + view_->ShowDevTools(activate); return; } + activate_ = activate; + // Show devtools only after it has done loading, this is to make sure the // SetIsDocked is called *BEFORE* ShowDevTools. embedder_message_dispatcher_.reset( @@ -430,7 +432,7 @@ void InspectableWebContentsImpl::CloseWindow() { void InspectableWebContentsImpl::LoadCompleted() { frontend_loaded_ = true; if (managed_devtools_web_contents_) - view_->ShowDevTools(); + view_->ShowDevTools(activate_); // If the devtools can dock, "SetIsDocked" will be called by devtools itself. if (!can_dock_) { @@ -501,7 +503,7 @@ void InspectableWebContentsImpl::LoadNetworkResource( void InspectableWebContentsImpl::SetIsDocked(const DispatchCallback& callback, bool docked) { if (managed_devtools_web_contents_) - view_->SetIsDocked(docked); + view_->SetIsDocked(docked, activate_); if (!callback.is_null()) callback.Run(nullptr); } diff --git a/atom/browser/ui/inspectable_web_contents_impl.h b/atom/browser/ui/inspectable_web_contents_impl.h index 4816fe7853569..8e15b6191e3e9 100644 --- a/atom/browser/ui/inspectable_web_contents_impl.h +++ b/atom/browser/ui/inspectable_web_contents_impl.h @@ -55,7 +55,7 @@ class InspectableWebContentsImpl void ReleaseWebContents() override; void SetDevToolsWebContents(content::WebContents* devtools) override; void SetDockState(const std::string& state) override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; void AttachTo(scoped_refptr) override; @@ -211,6 +211,7 @@ class InspectableWebContentsImpl gfx::Rect devtools_bounds_; bool can_dock_; std::string dock_state_; + bool activate_ = true; using PendingRequestsMap = std::map; PendingRequestsMap pending_requests_; diff --git a/atom/browser/ui/inspectable_web_contents_view.h b/atom/browser/ui/inspectable_web_contents_view.h index fea7b09ac8a86..1de44213c09a4 100644 --- a/atom/browser/ui/inspectable_web_contents_view.h +++ b/atom/browser/ui/inspectable_web_contents_view.h @@ -43,12 +43,12 @@ class InspectableWebContentsView { virtual gfx::NativeView GetNativeView() const = 0; #endif - virtual void ShowDevTools() = 0; + virtual void ShowDevTools(bool activate) = 0; // Hide the DevTools view. virtual void CloseDevTools() = 0; virtual bool IsDevToolsViewShowing() = 0; virtual bool IsDevToolsViewFocused() = 0; - virtual void SetIsDocked(bool docked) = 0; + virtual void SetIsDocked(bool docked, bool activate) = 0; virtual void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) = 0; virtual void SetTitle(const base::string16& title) = 0; diff --git a/atom/browser/ui/inspectable_web_contents_view_mac.h b/atom/browser/ui/inspectable_web_contents_view_mac.h index d09581e6a6aef..49ff8db367214 100644 --- a/atom/browser/ui/inspectable_web_contents_view_mac.h +++ b/atom/browser/ui/inspectable_web_contents_view_mac.h @@ -23,11 +23,11 @@ class InspectableWebContentsViewMac : public InspectableWebContentsView { ~InspectableWebContentsViewMac() override; gfx::NativeView GetNativeView() const override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; bool IsDevToolsViewFocused() override; - void SetIsDocked(bool docked) override; + void SetIsDocked(bool docked, bool activate) override; void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; void SetTitle(const base::string16& title) override; diff --git a/atom/browser/ui/inspectable_web_contents_view_mac.mm b/atom/browser/ui/inspectable_web_contents_view_mac.mm index 956446b486c9f..838ef9bb23f95 100644 --- a/atom/browser/ui/inspectable_web_contents_view_mac.mm +++ b/atom/browser/ui/inspectable_web_contents_view_mac.mm @@ -34,12 +34,12 @@ return view_.get(); } -void InspectableWebContentsViewMac::ShowDevTools() { - [view_ setDevToolsVisible:YES]; +void InspectableWebContentsViewMac::ShowDevTools(bool activate) { + [view_ setDevToolsVisible:YES activate:activate]; } void InspectableWebContentsViewMac::CloseDevTools() { - [view_ setDevToolsVisible:NO]; + [view_ setDevToolsVisible:NO activate:NO]; } bool InspectableWebContentsViewMac::IsDevToolsViewShowing() { @@ -50,8 +50,8 @@ return [view_ isDevToolsFocused]; } -void InspectableWebContentsViewMac::SetIsDocked(bool docked) { - [view_ setIsDocked:docked]; +void InspectableWebContentsViewMac::SetIsDocked(bool docked, bool activate) { + [view_ setIsDocked:docked activate:activate]; } void InspectableWebContentsViewMac::SetContentsResizingStrategy( diff --git a/atom/browser/ui/views/inspectable_web_contents_view_views.cc b/atom/browser/ui/views/inspectable_web_contents_view_views.cc index b3e63f1cbc8cc..69d593f86d589 100644 --- a/atom/browser/ui/views/inspectable_web_contents_view_views.cc +++ b/atom/browser/ui/views/inspectable_web_contents_view_views.cc @@ -115,7 +115,7 @@ views::View* InspectableWebContentsViewViews::GetWebView() { return contents_web_view_; } -void InspectableWebContentsViewViews::ShowDevTools() { +void InspectableWebContentsViewViews::ShowDevTools(bool activate) { if (devtools_visible_) return; @@ -125,7 +125,11 @@ void InspectableWebContentsViewViews::ShowDevTools() { inspectable_web_contents_->GetDevToolsWebContents()); devtools_window_->SetBounds( inspectable_web_contents()->GetDevToolsBounds()); - devtools_window_->Show(); + if (activate) { + devtools_window_->Show(); + } else { + devtools_window_->ShowInactive(); + } } else { devtools_web_view_->SetVisible(true); devtools_web_view_->SetWebContents( @@ -166,7 +170,7 @@ bool InspectableWebContentsViewViews::IsDevToolsViewFocused() { return false; } -void InspectableWebContentsViewViews::SetIsDocked(bool docked) { +void InspectableWebContentsViewViews::SetIsDocked(bool docked, bool activate) { CloseDevTools(); if (!docked) { @@ -191,7 +195,7 @@ void InspectableWebContentsViewViews::SetIsDocked(bool docked) { devtools_window_->UpdateWindowIcon(); } - ShowDevTools(); + ShowDevTools(activate); } void InspectableWebContentsViewViews::SetContentsResizingStrategy( diff --git a/atom/browser/ui/views/inspectable_web_contents_view_views.h b/atom/browser/ui/views/inspectable_web_contents_view_views.h index a4d2578f969de..05336d3e9dc75 100644 --- a/atom/browser/ui/views/inspectable_web_contents_view_views.h +++ b/atom/browser/ui/views/inspectable_web_contents_view_views.h @@ -32,11 +32,11 @@ class InspectableWebContentsViewViews : public InspectableWebContentsView, // InspectableWebContentsView: views::View* GetView() override; views::View* GetWebView() override; - void ShowDevTools() override; + void ShowDevTools(bool activate) override; void CloseDevTools() override; bool IsDevToolsViewShowing() override; bool IsDevToolsViewFocused() override; - void SetIsDocked(bool docked) override; + void SetIsDocked(bool docked, bool activate) override; void SetContentsResizingStrategy( const DevToolsContentsResizingStrategy& strategy) override; void SetTitle(const base::string16& title) override; diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 3e1a9183da508..9f78c07b66e59 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1245,8 +1245,10 @@ app.once('ready', () => { * `options` Object (optional) * `mode` String - Opens the devtools with specified dock state, can be - `right`, `bottom`, `undocked`, `detach`. Defaults to last used dock state. - In `undocked` mode it's possible to dock back. In `detach` mode it's not. + `right`, `bottom`, `undocked`, `detach`. Defaults to last used dock state. + In `undocked` mode it's possible to dock back. In `detach` mode it's not. + * `activate` Boolean (optional) - Whether to bring the opened devtools window + to the foreground. The default is `true`. Opens the devtools. diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index 0791d7aea7bbb..ff62e8aaf3bde 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -159,6 +159,22 @@ describe('webContents module', () => { }) }) + describe('openDevTools() API', () => { + it('can show window with activation', async () => { + w.show() + assert.strictEqual(w.isFocused(), true) + w.webContents.openDevTools({ mode: 'detach', activate: true }) + await emittedOnce(w.webContents, 'devtools-opened') + assert.strictEqual(w.isFocused(), false) + }) + + it('can show window without activation', async () => { + w.webContents.openDevTools({ mode: 'detach', activate: false }) + await emittedOnce(w.webContents, 'devtools-opened') + assert.strictEqual(w.isDevToolsOpened(), true) + }) + }) + describe('before-input-event event', () => { it('can prevent document keyboard events', (done) => { ipcMain.once('keydown', (event, key) => {