Place DevTools WebContents underneath inspected WebContents.

This commit has this strategy implemented on Mac.

See https://code.google.com/p/chromium/issues/detail?id=318751.
This commit is contained in:
Cheng Zhao 2014-07-02 16:21:47 +08:00
parent 7d130c9697
commit 2efeaa268f
13 changed files with 370 additions and 91 deletions

View file

@ -40,6 +40,8 @@
'browser/default_web_contents_delegate.cc',
'browser/default_web_contents_delegate.h',
'browser/default_web_contents_delegate_mac.mm',
'browser/devtools_contents_resizing_strategy.cc',
'browser/devtools_contents_resizing_strategy.h',
'browser/devtools_embedder_message_dispatcher.cc',
'browser/devtools_embedder_message_dispatcher.h',
'browser/devtools_ui.cc',

View file

@ -0,0 +1,85 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "browser/devtools_contents_resizing_strategy.h"
#include <algorithm>
DevToolsContentsResizingStrategy::DevToolsContentsResizingStrategy() {
}
DevToolsContentsResizingStrategy::DevToolsContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size)
: insets_(insets),
min_size_(min_size) {
}
DevToolsContentsResizingStrategy::DevToolsContentsResizingStrategy(
const gfx::Rect& bounds)
: bounds_(bounds) {
}
void DevToolsContentsResizingStrategy::CopyFrom(
const DevToolsContentsResizingStrategy& strategy) {
insets_ = strategy.insets();
min_size_ = strategy.min_size();
bounds_ = strategy.bounds();
}
bool DevToolsContentsResizingStrategy::Equals(
const DevToolsContentsResizingStrategy& strategy) {
return insets_ == strategy.insets() && min_size_ == strategy.min_size() &&
bounds_ == strategy.bounds();
}
void ApplyDevToolsContentsResizingStrategy(
const DevToolsContentsResizingStrategy& strategy,
const gfx::Size& container_size,
const gfx::Rect& old_devtools_bounds,
const gfx::Rect& old_contents_bounds,
gfx::Rect* new_devtools_bounds,
gfx::Rect* new_contents_bounds) {
new_devtools_bounds->SetRect(
0, 0, container_size.width(), container_size.height());
const gfx::Insets& insets = strategy.insets();
const gfx::Size& min_size = strategy.min_size();
const gfx::Rect& bounds = strategy.bounds();
if (!bounds.size().IsEmpty()) {
int left = std::min(bounds.x(), container_size.width());
int top = std::min(bounds.y(), container_size.height());
int width = std::min(bounds.width(), container_size.width() - left);
int height = std::min(bounds.height(), container_size.height() - top);
new_contents_bounds->SetRect(left, top, width, height);
return;
}
int width = std::max(0, container_size.width() - insets.width());
int left = insets.left();
if (width < min_size.width() && insets.width() > 0) {
int min_width = std::min(min_size.width(), container_size.width());
int insets_width = container_size.width() - min_width;
int insets_decrease = insets.width() - insets_width;
// Decrease both left and right insets proportionally.
left -= insets_decrease * insets.left() / insets.width();
width = min_width;
}
left = std::max(0, std::min(container_size.width(), left));
int height = std::max(0, container_size.height() - insets.height());
int top = insets.top();
if (height < min_size.height() && insets.height() > 0) {
int min_height = std::min(min_size.height(), container_size.height());
int insets_height = container_size.height() - min_height;
int insets_decrease = insets.height() - insets_height;
// Decrease both top and bottom insets proportionally.
top -= insets_decrease * insets.top() / insets.height();
height = min_height;
}
top = std::max(0, std::min(container_size.height(), top));
new_contents_bounds->SetRect(left, top, width, height);
}

View file

@ -0,0 +1,56 @@
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BRIGHTRAY_BROWSER_DEVTOOLS_CONTENTS_RESIZING_STRATEGY_H_
#define BRIGHTRAY_BROWSER_DEVTOOLS_CONTENTS_RESIZING_STRATEGY_H_
#include "base/basictypes.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
// This class knows how to resize both DevTools and inspected WebContents
// inside a browser window hierarchy.
class DevToolsContentsResizingStrategy {
public:
DevToolsContentsResizingStrategy();
DevToolsContentsResizingStrategy(
const gfx::Insets& insets,
const gfx::Size& min_size);
explicit DevToolsContentsResizingStrategy(const gfx::Rect& bounds);
void CopyFrom(const DevToolsContentsResizingStrategy& strategy);
bool Equals(const DevToolsContentsResizingStrategy& strategy);
const gfx::Insets& insets() const { return insets_; }
const gfx::Size& min_size() const { return min_size_; }
const gfx::Rect& bounds() const { return bounds_; }
private:
// Insets of contents inside DevTools.
gfx::Insets insets_;
// Minimum size of contents.
gfx::Size min_size_;
// Contents bounds. When non-empty, used instead of insets.
gfx::Rect bounds_;
DISALLOW_COPY_AND_ASSIGN(DevToolsContentsResizingStrategy);
};
// Applies contents resizing strategy, producing bounds for devtools and
// page contents views. Generally, page contents view is placed atop of devtools
// inside a common parent view, which size should be passed in |container_size|.
// When unknown, providing empty rect as previous devtools and contents bounds
// is allowed.
void ApplyDevToolsContentsResizingStrategy(
const DevToolsContentsResizingStrategy& strategy,
const gfx::Size& container_size,
const gfx::Rect& old_devtools_bounds,
const gfx::Rect& old_contents_bounds,
gfx::Rect* new_devtools_bounds,
gfx::Rect* new_contents_bounds);
#endif // BRIGHTRAY_BROWSER_DEVTOOLS_CONTENTS_RESIZING_STRATEGY_H_

View file

@ -27,6 +27,36 @@ bool GetValue(const base::ListValue& list, int pos, bool& value) {
return list.GetBoolean(pos, &value);
}
bool GetValue(const base::ListValue& list, int pos, gfx::Insets& insets) {
const base::DictionaryValue* dict;
if (!list.GetDictionary(pos, &dict))
return false;
int top = 0;
int left = 0;
int bottom = 0;
int right = 0;
if (!dict->GetInteger("top", &top) ||
!dict->GetInteger("left", &left) ||
!dict->GetInteger("bottom", &bottom) ||
!dict->GetInteger("right", &right))
return false;
insets.Set(top, left, bottom, right);
return true;
}
bool GetValue(const base::ListValue& list, int pos, gfx::Size& size) {
const base::DictionaryValue* dict;
if (!list.GetDictionary(pos, &dict))
return false;
int width = 0;
int height = 0;
if (!dict->GetInteger("width", &width) ||
!dict->GetInteger("height", &height))
return false;
size.SetSize(width, height);
return true;
}
template <typename T>
struct StorageTraits {
typedef T StorageType;
@ -105,6 +135,28 @@ bool ParseAndHandle3(const base::Callback<void(A1, A2, A3)>& handler,
return true;
}
template <class A1, class A2, class A3, class A4>
bool ParseAndHandle3(const base::Callback<void(A1, A2, A3, A4)>& handler,
const base::ListValue& list) {
if (list.GetSize() != 3)
return false;
Argument<A1> arg1(list, 0);
if (!arg1.valid())
return false;
Argument<A2> arg2(list, 1);
if (!arg2.valid())
return false;
Argument<A3> arg3(list, 2);
if (!arg3.valid())
return false;
Argument<A4> arg4(list, 3);
if (!arg4.valid())
return false;
handler.Run(arg1.value(), arg2.value(), arg3.value(), arg4.value());
return true;
}
typedef base::Callback<bool (const base::ListValue&)> ListValueParser;
ListValueParser BindToListParser(const base::Callback<void()>& handler) {
@ -127,6 +179,12 @@ ListValueParser BindToListParser(
return base::Bind(&ParseAndHandle3<A1, A2, A3>, handler);
}
template <class A1, class A2, class A3, class A4>
ListValueParser BindToListParser(
const base::Callback<void(A1, A2, A3, A4)>& handler) {
return base::Bind(&ParseAndHandle3<A1, A2, A3, A4>, handler);
}
} // namespace
DevToolsEmbedderMessageDispatcher::DevToolsEmbedderMessageDispatcher(
@ -137,11 +195,14 @@ DevToolsEmbedderMessageDispatcher::DevToolsEmbedderMessageDispatcher(
RegisterHandler("closeWindow",
BindToListParser(base::Bind(&Delegate::CloseWindow,
base::Unretained(delegate))));
RegisterHandler("setContentsResizingStrategy",
BindToListParser(base::Bind(&Delegate::SetContentsResizingStrategy,
base::Unretained(delegate))));
RegisterHandler("moveWindowBy",
BindToListParser(base::Bind(&Delegate::MoveWindow,
base::Unretained(delegate))));
RegisterHandler("requestSetDockSide",
BindToListParser(base::Bind(&Delegate::SetDockSide,
RegisterHandler("setIsDocked",
BindToListParser(base::Bind(&Delegate::SetIsDocked,
base::Unretained(delegate))));
RegisterHandler("openInNewTab",
BindToListParser(base::Bind(&Delegate::OpenInNewTab,

View file

@ -9,6 +9,8 @@
#include <string>
#include "base/callback.h"
#include "ui/gfx/insets.h"
#include "ui/gfx/size.h"
namespace base {
class ListValue;
@ -30,8 +32,10 @@ class DevToolsEmbedderMessageDispatcher {
virtual void ActivateWindow() = 0;
virtual void CloseWindow() = 0;
virtual void SetContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size) = 0;
virtual void MoveWindow(int x, int y) = 0;
virtual void SetDockSide(const std::string& side) = 0;
virtual void SetIsDocked(bool docked) = 0;
virtual void OpenInNewTab(const std::string& url) = 0;
virtual void SaveToFile(const std::string& url,
const std::string& content,

View file

@ -9,18 +9,6 @@ class InspectableWebContentsDelegate {
public:
virtual ~InspectableWebContentsDelegate() {}
// Called when the devtools is going to change the dock side, returning true
// to override the default behavior.
// Receiver should set |succeed| to |false| if it failed to handle this.
virtual bool DevToolsSetDockSide(const std::string& side, bool* succeed) {
return false;
}
// Called when the devtools is going to be showed, returning true to override
// the default behavior.
// Receiver is given the chance to change the |dock_side|.
virtual bool DevToolsShow(std::string* dock_side) { return false; }
// Requested by WebContents of devtools.
virtual void DevToolsSaveToFile(
const std::string& url, const std::string& content, bool save_as) {}

View file

@ -26,8 +26,8 @@ namespace brightray {
namespace {
const char kChromeUIDevToolsURL[] = "chrome-devtools://devtools/devtools.html";
const char kDockSidePref[] = "brightray.devtools.dockside";
const char kChromeUIDevToolsURL[] = "chrome-devtools://devtools/devtools.html?can_dock=true";
const char kIsDockedPref[] = "brightray.devtools.isDocked";
}
@ -36,7 +36,7 @@ InspectableWebContentsView* CreateInspectableContentsView(
InspectableWebContentsImpl* inspectable_web_contents_impl);
void InspectableWebContentsImpl::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterStringPref(kDockSidePref, "bottom");
registry->RegisterBooleanPref(kIsDockedPref, true);
}
InspectableWebContentsImpl::InspectableWebContentsImpl(
@ -45,7 +45,7 @@ InspectableWebContentsImpl::InspectableWebContentsImpl(
delegate_(nullptr) {
auto context = static_cast<BrowserContext*>(
web_contents_->GetBrowserContext());
dock_side_ = context->prefs()->GetString(kDockSidePref);
is_docked_ = context->prefs()->GetBoolean(kIsDockedPref);
view_.reset(CreateInspectableContentsView(this));
}
@ -62,6 +62,8 @@ content::WebContents* InspectableWebContentsImpl::GetWebContents() const {
}
void InspectableWebContentsImpl::ShowDevTools() {
// Show devtools only after it has done loading, this is to make sure the
// SetIsDocked is called *BEFORE* ShowDevTools.
if (!devtools_web_contents_) {
embedder_message_dispatcher_.reset(
new DevToolsEmbedderMessageDispatcher(this));
@ -70,11 +72,6 @@ void InspectableWebContentsImpl::ShowDevTools() {
web_contents_->GetBrowserContext());
devtools_web_contents_.reset(content::WebContents::Create(create_params));
#if defined(OS_MACOSX)
// Work around http://crbug.com/279472.
devtools_web_contents_->GetView()->SetAllowOverlappingViews(true);
#endif
Observe(devtools_web_contents_.get());
devtools_web_contents_->SetDelegate(this);
@ -92,17 +89,13 @@ void InspectableWebContentsImpl::ShowDevTools() {
content::Referrer(),
content::PAGE_TRANSITION_AUTO_TOPLEVEL,
std::string());
}
if (delegate_ && delegate_->DevToolsShow(&dock_side_))
return;
view_->SetDockSide(dock_side_);
} else {
view_->ShowDevTools();
}
}
void InspectableWebContentsImpl::CloseDevTools() {
if (IsDevToolsViewShowing()) {
if (devtools_web_contents_) {
view_->CloseDevTools();
devtools_web_contents_.reset();
web_contents_->GetView()->Focus();
@ -113,13 +106,6 @@ bool InspectableWebContentsImpl::IsDevToolsViewShowing() {
return devtools_web_contents_ && view_->IsDevToolsViewShowing();
}
void InspectableWebContentsImpl::UpdateFrontendDockSide() {
auto javascript = base::StringPrintf(
"InspectorFrontendAPI.setDockSide(\"%s\")", dock_side_.c_str());
devtools_web_contents_->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
base::string16(), base::ASCIIToUTF16(javascript));
}
void InspectableWebContentsImpl::ActivateWindow() {
}
@ -127,25 +113,26 @@ void InspectableWebContentsImpl::CloseWindow() {
CloseDevTools();
}
void InspectableWebContentsImpl::SetContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size) {
DevToolsContentsResizingStrategy strategy(insets, min_size);
if (contents_resizing_strategy_.Equals(strategy))
return;
contents_resizing_strategy_.CopyFrom(strategy);
view_->SetContentsResizingStrategy(contents_resizing_strategy_);
}
void InspectableWebContentsImpl::MoveWindow(int x, int y) {
}
void InspectableWebContentsImpl::SetDockSide(const std::string& side) {
bool succeed = true;
if (delegate_ && delegate_->DevToolsSetDockSide(side, &succeed)) {
if (!succeed) // delegate failed to set dock side.
return;
} else if (!view_->SetDockSide(side)) {
return;
}
dock_side_ = side;
void InspectableWebContentsImpl::SetIsDocked(bool docked) {
view_->SetIsDocked(docked);
is_docked_ = docked;
auto context = static_cast<BrowserContext*>(
web_contents_->GetBrowserContext());
context->prefs()->SetString(kDockSidePref, side);
UpdateFrontendDockSide();
context->prefs()->SetBoolean(kIsDockedPref, docked);
}
void InspectableWebContentsImpl::OpenInNewTab(const std::string& url) {
@ -207,7 +194,7 @@ void InspectableWebContentsImpl::DidFinishLoad(int64 frame_id,
if (!is_main_frame)
return;
UpdateFrontendDockSide();
view_->ShowDevTools();
}
void InspectableWebContentsImpl::WebContentsDestroyed(content::WebContents*) {

View file

@ -8,6 +8,7 @@
#include "browser/inspectable_web_contents.h"
#include "browser/devtools_contents_resizing_strategy.h"
#include "browser/devtools_embedder_message_dispatcher.h"
#include "content/public/browser/devtools_frontend_host_delegate.h"
@ -54,14 +55,14 @@ class InspectableWebContentsImpl :
}
private:
void UpdateFrontendDockSide();
// DevToolsEmbedderMessageDispacher::Delegate
virtual void ActivateWindow() OVERRIDE;
virtual void CloseWindow() OVERRIDE;
virtual void SetContentsResizingStrategy(
const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE;
virtual void MoveWindow(int x, int y) OVERRIDE;
virtual void SetDockSide(const std::string& side) OVERRIDE;
virtual void SetIsDocked(bool docked) OVERRIDE;
virtual void OpenInNewTab(const std::string& url) OVERRIDE;
virtual void SaveToFile(const std::string& url,
const std::string& content,
@ -103,7 +104,9 @@ class InspectableWebContentsImpl :
scoped_ptr<content::WebContents> devtools_web_contents_;
scoped_ptr<InspectableWebContentsView> view_;
scoped_refptr<content::DevToolsAgentHost> agent_host_;
std::string dock_side_;
bool is_docked_;
DevToolsContentsResizingStrategy contents_resizing_strategy_;
scoped_ptr<DevToolsEmbedderMessageDispatcher> embedder_message_dispatcher_;

View file

@ -3,6 +3,8 @@
#include "ui/gfx/native_widget_types.h"
class DevToolsContentsResizingStrategy;
namespace brightray {
class InspectableWebContentsView {
@ -15,7 +17,9 @@ class InspectableWebContentsView {
// Hide the DevTools view.
virtual void CloseDevTools() = 0;
virtual bool IsDevToolsViewShowing() = 0;
virtual bool SetDockSide(const std::string& side) = 0;
virtual void SetIsDocked(bool docked) = 0;
virtual void SetContentsResizingStrategy(
const DevToolsContentsResizingStrategy& strategy) = 0;
};
} // namespace brightray

View file

@ -21,7 +21,9 @@ class InspectableWebContentsViewMac : public InspectableWebContentsView {
virtual void ShowDevTools() OVERRIDE;
virtual void CloseDevTools() OVERRIDE;
virtual bool IsDevToolsViewShowing() OVERRIDE;
virtual bool SetDockSide(const std::string& side) OVERRIDE;
virtual void SetIsDocked(bool docked) OVERRIDE;
virtual void SetContentsResizingStrategy(
const DevToolsContentsResizingStrategy& strategy) OVERRIDE;
InspectableWebContentsImpl* inspectable_web_contents() {
return inspectable_web_contents_;

View file

@ -1,10 +1,11 @@
#import "browser/inspectable_web_contents_view_mac.h"
#include "browser/inspectable_web_contents_view_mac.h"
#import "browser/inspectable_web_contents.h"
#import <AppKit/AppKit.h>
#include "browser/inspectable_web_contents.h"
#import "browser/mac/bry_inspectable_web_contents_view.h"
#import "content/public/browser/web_contents_view.h"
#import <AppKit/AppKit.h>
#include "content/public/browser/web_contents_view.h"
namespace brightray {
@ -36,8 +37,13 @@ bool InspectableWebContentsViewMac::IsDevToolsViewShowing() {
return [view_ isDevToolsVisible];
}
bool InspectableWebContentsViewMac::SetDockSide(const std::string& side) {
return [view_ setDockSide:side];
void InspectableWebContentsViewMac::SetIsDocked(bool docked) {
[view_ setIsDocked:docked];
}
void InspectableWebContentsViewMac::SetContentsResizingStrategy(
const DevToolsContentsResizingStrategy& strategy) {
[view_ setContentsResizingStrategy:strategy];
}
}

View file

@ -1,24 +1,33 @@
#import <AppKit/AppKit.h>
#include <string>
#include "browser/devtools_contents_resizing_strategy.h"
#include "base/mac/scoped_nsobject.h"
#include "ui/base/cocoa/base_view.h"
#include "ui/gfx/insets.h"
namespace brightray {
class InspectableWebContentsViewMac;
}
@interface BRYInspectableWebContentsView : NSView<NSWindowDelegate> {
@interface BRYInspectableWebContentsView : BaseView<NSWindowDelegate> {
@private
brightray::InspectableWebContentsViewMac* inspectableWebContentsView_;
base::scoped_nsobject<NSWindow> devtools_window_;
BOOL devtools_visible_;
BOOL devtools_docked_;
DevToolsContentsResizingStrategy strategy_;
}
- (instancetype)initWithInspectableWebContentsViewMac:(brightray::InspectableWebContentsViewMac*)inspectableWebContentsView;
- (IBAction)showDevTools:(id)sender;
- (void)setDevToolsVisible:(BOOL)visible;
- (BOOL)isDevToolsVisible;
- (BOOL)setDockSide:(const std::string&)side ;
- (void)setIsDocked:(BOOL)docked;
- (void)setContentsResizingStrategy:(const DevToolsContentsResizingStrategy&)strategy;
// Adjust docked devtools to the contents resizing strategy.
- (void)update;
@end

View file

@ -1,11 +1,12 @@
#import "browser/mac/bry_inspectable_web_contents_view.h"
#include "browser/mac/bry_inspectable_web_contents_view.h"
#import "browser/inspectable_web_contents_impl.h"
#import "browser/inspectable_web_contents_view_mac.h"
#include "browser/inspectable_web_contents_impl.h"
#include "browser/inspectable_web_contents_view_mac.h"
#import "content/public/browser/render_widget_host_view.h"
#import "content/public/browser/web_contents_view.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_view.h"
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
#include "ui/gfx/mac/scoped_ns_disable_screen_updates.h"
using namespace brightray;
@ -18,10 +19,12 @@ using namespace brightray;
inspectableWebContentsView_ = inspectableWebContentsView;
devtools_visible_ = NO;
devtools_docked_ = NO;
auto webView = inspectableWebContentsView->inspectable_web_contents()->GetWebContents()->GetView()->GetNativeView();
webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[self addSubview:webView];
auto contents = inspectableWebContentsView->inspectable_web_contents()->GetWebContents();
auto contentsView = contents->GetView()->GetNativeView();
[contentsView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[self addSubview:contentsView];
return self;
}
@ -30,16 +33,53 @@ using namespace brightray;
[super dealloc];
}
- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
[self adjustSubviews];
}
- (IBAction)showDevTools:(id)sender {
inspectableWebContentsView_->inspectable_web_contents()->ShowDevTools();
}
- (void)setDevToolsVisible:(BOOL)visible {
if (devtools_visible_ == visible)
if (visible == devtools_visible_)
return;
devtools_visible_ = visible;
if (!devtools_window_) {
auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents();
auto devToolsView = devToolsWebContents->GetView()->GetNativeView();
devtools_visible_ = visible;
if (devtools_docked_) {
if (visible) {
// Place the devToolsView under contentsView, notice that we didn't set
// sizes for them until the setContentsResizingStrategy message.
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
[self update];
} else {
gfx::ScopedNSDisableScreenUpdates disabler;
devToolsWebContents->GetView()->RemoveOverlayView();
[devToolsView removeFromSuperview];
[self adjustSubviews];
}
} else {
if (visible)
[devtools_window_ makeKeyAndOrderFront:nil];
else
devtools_window_.reset();
}
}
- (BOOL)isDevToolsVisible {
return devtools_visible_;
}
- (void)setIsDocked:(BOOL)docked {
// Revert to no-devtools state.
[self setDevToolsVisible:NO];
// Switch to new state.
devtools_docked_ = docked;
if (!docked) {
auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents();
auto devToolsView = devToolsWebContents->GetView()->GetNativeView();
@ -65,27 +105,59 @@ using namespace brightray;
[contentView addSubview:devToolsView];
}
[self setDevToolsVisible:YES];
}
if (visible) {
[devtools_window_ makeKeyAndOrderFront:nil];
} else {
[devtools_window_ performClose:nil];
- (void)setContentsResizingStrategy:(const DevToolsContentsResizingStrategy&)strategy {
strategy_.CopyFrom(strategy);
[self update];
}
- (void)update {
if (!devtools_docked_)
return;
auto contents = inspectableWebContentsView_->inspectable_web_contents()->GetWebContents();
auto devToolsWebContents = inspectableWebContentsView_->inspectable_web_contents()->devtools_web_contents();
gfx::ScopedNSDisableScreenUpdates disabler;
devToolsWebContents->GetView()->SetOverlayView(
contents->GetView(),
gfx::Point(strategy_.insets().left(), strategy_.insets().top()));
[self adjustSubviews];
}
- (void)adjustSubviews {
if (![[self subviews] count])
return;
if (![self isDevToolsVisible] || devtools_window_) {
DCHECK_EQ(1u, [[self subviews] count]);
NSView* contents = [[self subviews] objectAtIndex:0];
[contents setFrame:[self bounds]];
return;
}
}
- (BOOL)isDevToolsVisible {
return devtools_visible_;
}
NSView* devToolsView = [[self subviews] objectAtIndex:0];
NSView* contentsView = [[self subviews] objectAtIndex:1];
- (BOOL)setDockSide:(const std::string&)side {
return NO;
DCHECK_EQ(2u, [[self subviews] count]);
gfx::Rect new_devtools_bounds;
gfx::Rect new_contents_bounds;
ApplyDevToolsContentsResizingStrategy(
strategy_, gfx::Size(NSSizeToCGSize([self bounds].size)),
[self flipNSRectToRect:[devToolsView bounds]],
[self flipNSRectToRect:[contentsView bounds]],
&new_devtools_bounds, &new_contents_bounds);
[devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
[contentsView setFrame:[self flipRectToNSRect:new_contents_bounds]];
}
#pragma mark - NSWindowDelegate
- (void)windowWillClose:(NSNotification*)notification {
devtools_visible_ = NO;
devtools_window_.reset();
inspectableWebContentsView_->inspectable_web_contents()->CloseDevTools();
}
@end