From 4e69bd17336aa50675dcfa26aae054daf8e9d2ea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 09:10:26 +0800 Subject: [PATCH 1/8] Add 'third_party/skia/include/core' to include_dirs. --- brightray/brightray.gyp | 1 + 1 file changed, 1 insertion(+) diff --git a/brightray/brightray.gyp b/brightray/brightray.gyp index 532011bc9558..8dd2a64ce089 100644 --- a/brightray/brightray.gyp +++ b/brightray/brightray.gyp @@ -13,6 +13,7 @@ '.', '<(libchromiumcontent_include_dir)', '<(libchromiumcontent_include_dir)/third_party/skia/include/config', + '<(libchromiumcontent_include_dir)/third_party/skia/include/core', ], 'direct_dependent_settings': { 'include_dirs': [ From b0374b6a1d20ca6e902f4ab64af8806bf9b9a0ea Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 09:58:28 +0800 Subject: [PATCH 2/8] Use views::View to represent web view. --- .../win/inspectable_web_contents_view_win.cc | 44 ++++++++++++++++++- .../win/inspectable_web_contents_view_win.h | 9 ++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index dca7ba4f3ebd..00c661c22b2d 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -6,6 +6,8 @@ #include "content/public/browser/web_contents_view.h" #include "ui/gfx/win/hwnd_util.h" +#include "ui/views/controls/webview/webview.h" +#include "ui/views/view.h" namespace brightray { @@ -15,6 +17,41 @@ const int kWindowInset = 100; } +class ContainerView : public views::View { + public: + explicit ContainerView(InspectableWebContentsViewWin* web_contents_view) + : container_view_created_(false), + web_view_(new views::WebView(NULL)), + web_contents_view_(web_contents_view) { + web_view_->SetWebContents( + web_contents_view_->inspectable_web_contents()->GetWebContents()); + } + + private: + // views::View: + virtual void Layout() OVERRIDE { + web_view_->SetBounds(0, 0, width(), height()); + } + + virtual void ViewHierarchyChanged( + const ViewHierarchyChangedDetails& details) OVERRIDE { + View::ViewHierarchyChanged(details); + // We're not using child == this because a Widget may not be + // available when this is added to the hierarchy. + if (details.is_add && GetWidget() && !container_view_created_) { + container_view_created_ = true; + AddChildView(web_view_); + } + } + + // True if the container view has already been created, or false otherwise. + bool container_view_created_; + + views::WebView* web_view_; + + InspectableWebContentsViewWin* web_contents_view_; +}; + InspectableWebContentsView* CreateInspectableContentsView( InspectableWebContentsImpl* inspectable_web_contents) { return new InspectableWebContentsViewWin(inspectable_web_contents); @@ -22,7 +59,8 @@ InspectableWebContentsView* CreateInspectableContentsView( InspectableWebContentsViewWin::InspectableWebContentsViewWin( InspectableWebContentsImpl* inspectable_web_contents) - : inspectable_web_contents_(inspectable_web_contents) { + : inspectable_web_contents_(inspectable_web_contents), + container_(new ContainerView(this)) { } InspectableWebContentsViewWin::~InspectableWebContentsViewWin() { @@ -30,6 +68,10 @@ InspectableWebContentsViewWin::~InspectableWebContentsViewWin() { DestroyWindow(devtools_window_->hwnd()); } +views::View* InspectableWebContentsViewWin::GetView() const { + return container_; +} + gfx::NativeView InspectableWebContentsViewWin::GetNativeView() const { auto web_contents = inspectable_web_contents_->GetWebContents(); return web_contents->GetView()->GetNativeView(); diff --git a/brightray/browser/win/inspectable_web_contents_view_win.h b/brightray/browser/win/inspectable_web_contents_view_win.h index 55b09b2d3e4c..382a0f460298 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.h +++ b/brightray/browser/win/inspectable_web_contents_view_win.h @@ -6,8 +6,13 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" +namespace views { +class View; +} + namespace brightray { +class ContainerView; class DevToolsWindow; class InspectableWebContentsImpl; @@ -17,6 +22,8 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { InspectableWebContentsImpl* inspectable_web_contents_impl); ~InspectableWebContentsViewWin(); + views::View* GetView() const; + virtual gfx::NativeView GetNativeView() const OVERRIDE; virtual void ShowDevTools() OVERRIDE; virtual void CloseDevTools() OVERRIDE; @@ -31,6 +38,8 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { // Owns us. InspectableWebContentsImpl* inspectable_web_contents_; + ContainerView* container_; + base::WeakPtr devtools_window_; DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsViewWin); From 566022cb6667d84e25194392bda2ad6fcd14f7bf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 10:03:35 +0800 Subject: [PATCH 3/8] ContainerView should manage itself. --- brightray/browser/win/inspectable_web_contents_view_win.cc | 3 ++- brightray/browser/win/inspectable_web_contents_view_win.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index 00c661c22b2d..65b9ff176032 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -23,6 +23,7 @@ class ContainerView : public views::View { : container_view_created_(false), web_view_(new views::WebView(NULL)), web_contents_view_(web_contents_view) { + set_owned_by_client(); web_view_->SetWebContents( web_contents_view_->inspectable_web_contents()->GetWebContents()); } @@ -69,7 +70,7 @@ InspectableWebContentsViewWin::~InspectableWebContentsViewWin() { } views::View* InspectableWebContentsViewWin::GetView() const { - return container_; + return container_.get(); } gfx::NativeView InspectableWebContentsViewWin::GetNativeView() const { diff --git a/brightray/browser/win/inspectable_web_contents_view_win.h b/brightray/browser/win/inspectable_web_contents_view_win.h index 382a0f460298..5548f8ce75c2 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.h +++ b/brightray/browser/win/inspectable_web_contents_view_win.h @@ -4,6 +4,7 @@ #include "browser/inspectable_web_contents_view.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" namespace views { @@ -38,7 +39,7 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { // Owns us. InspectableWebContentsImpl* inspectable_web_contents_; - ContainerView* container_; + scoped_ptr container_; base::WeakPtr devtools_window_; From bd0f9df96cb3d7f4fd9900614443bc1c5311820f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 10:29:39 +0800 Subject: [PATCH 4/8] Put devtools in split view. --- .../win/inspectable_web_contents_view_win.cc | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index 65b9ff176032..89d4ade98cb8 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -6,6 +6,7 @@ #include "content/public/browser/web_contents_view.h" #include "ui/gfx/win/hwnd_util.h" +#include "ui/views/controls/single_split_view.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/view.h" @@ -24,14 +25,49 @@ class ContainerView : public views::View { web_view_(new views::WebView(NULL)), web_contents_view_(web_contents_view) { set_owned_by_client(); + web_view_->set_owned_by_client(); web_view_->SetWebContents( web_contents_view_->inspectable_web_contents()->GetWebContents()); } + void ShowDevTools() { + if (IsDevToolsViewShowing()) + return; + + RemoveChildView(web_view_.get()); + devtools_view_ = new views::WebView(NULL); + devtools_view_->SetWebContents(web_contents_view_-> + inspectable_web_contents()->devtools_web_contents()); + split_view_.reset(new views::SingleSplitView( + web_view_.get(), + devtools_view_, + views::SingleSplitView::VERTICAL_SPLIT, + NULL)); + AddChildView(split_view_.get()); + Layout(); + } + + void CloseDevTools() { + if (!IsDevToolsViewShowing()) + return; + + RemoveChildView(split_view_.get()); + split_view_.reset(); + AddChildView(web_view_.get()); + Layout(); + } + + bool IsDevToolsViewShowing() { + return split_view_; + } + private: // views::View: virtual void Layout() OVERRIDE { - web_view_->SetBounds(0, 0, width(), height()); + if (split_view_) + split_view_->SetBounds(0, 0, width(), height()); + else + web_view_->SetBounds(0, 0, width(), height()); } virtual void ViewHierarchyChanged( @@ -41,14 +77,16 @@ class ContainerView : public views::View { // available when this is added to the hierarchy. if (details.is_add && GetWidget() && !container_view_created_) { container_view_created_ = true; - AddChildView(web_view_); + AddChildView(web_view_.get()); } } // True if the container view has already been created, or false otherwise. bool container_view_created_; - views::WebView* web_view_; + scoped_ptr web_view_; + scoped_ptr split_view_; + views::WebView* devtools_view_; // Owned by split_view_. InspectableWebContentsViewWin* web_contents_view_; }; @@ -79,6 +117,9 @@ gfx::NativeView InspectableWebContentsViewWin::GetNativeView() const { } void InspectableWebContentsViewWin::ShowDevTools() { + container_->ShowDevTools(); + return; + if (!devtools_window_) { devtools_window_ = DevToolsWindow::Create(this)->AsWeakPtr(); devtools_window_->Init(HWND_DESKTOP, gfx::Rect()); @@ -95,13 +136,16 @@ void InspectableWebContentsViewWin::ShowDevTools() { } void InspectableWebContentsViewWin::CloseDevTools() { + container_->CloseDevTools(); + return; + if (!devtools_window_) return; SendMessage(devtools_window_->hwnd(), WM_CLOSE, 0, 0); } bool InspectableWebContentsViewWin::IsDevToolsViewShowing() { - return devtools_window_; + return container_->IsDevToolsViewShowing() || devtools_window_; } bool InspectableWebContentsViewWin::SetDockSide(const std::string& side) { From 1943d88bdce6d240e21e8797385291fd41309c6f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 11:37:07 +0800 Subject: [PATCH 5/8] Handle focus correctly. --- .../browser/win/inspectable_web_contents_view_win.cc | 9 +++++++++ .../browser/win/inspectable_web_contents_view_win.h | 1 + 2 files changed, 10 insertions(+) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index 89d4ade98cb8..88857e5e46ad 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -30,6 +30,10 @@ class ContainerView : public views::View { web_contents_view_->inspectable_web_contents()->GetWebContents()); } + views::View* GetWebView() const { + return web_view_.get(); + } + void ShowDevTools() { if (IsDevToolsViewShowing()) return; @@ -45,6 +49,7 @@ class ContainerView : public views::View { NULL)); AddChildView(split_view_.get()); Layout(); + devtools_view_->RequestFocus(); } void CloseDevTools() { @@ -111,6 +116,10 @@ views::View* InspectableWebContentsViewWin::GetView() const { return container_.get(); } +views::View* InspectableWebContentsViewWin::GetWebView() const { + return container_->GetWebView(); +} + gfx::NativeView InspectableWebContentsViewWin::GetNativeView() const { auto web_contents = inspectable_web_contents_->GetWebContents(); return web_contents->GetView()->GetNativeView(); diff --git a/brightray/browser/win/inspectable_web_contents_view_win.h b/brightray/browser/win/inspectable_web_contents_view_win.h index 5548f8ce75c2..e7d288affda0 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.h +++ b/brightray/browser/win/inspectable_web_contents_view_win.h @@ -24,6 +24,7 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { ~InspectableWebContentsViewWin(); views::View* GetView() const; + views::View* GetWebView() const; virtual gfx::NativeView GetNativeView() const OVERRIDE; virtual void ShowDevTools() OVERRIDE; From d70d24c3608e00008d83e9b03dc720493beedbf5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 12:03:20 +0800 Subject: [PATCH 6/8] Implement setting dock side. --- .../win/inspectable_web_contents_view_win.cc | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index 88857e5e46ad..02fe15c0f534 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -22,6 +22,7 @@ class ContainerView : public views::View { public: explicit ContainerView(InspectableWebContentsViewWin* web_contents_view) : container_view_created_(false), + dockside_("bottom"), web_view_(new views::WebView(NULL)), web_contents_view_(web_contents_view) { set_owned_by_client(); @@ -45,10 +46,12 @@ class ContainerView : public views::View { split_view_.reset(new views::SingleSplitView( web_view_.get(), devtools_view_, - views::SingleSplitView::VERTICAL_SPLIT, + GetSplitViewOrientation(), NULL)); + split_view_->set_divider_offset(GetSplitVievDividerOffset()); AddChildView(split_view_.get()); Layout(); + devtools_view_->RequestFocus(); } @@ -66,6 +69,22 @@ class ContainerView : public views::View { return split_view_; } + bool SetDockSide(const std::string& side) { + if (side != "bottom" && side != "right") + return false; // unsupported display location + if (dockside_ == side) + return true; // no change from current location + + dockside_ = side; + if (!IsDevToolsViewShowing()) + return true; + + split_view_->set_orientation(GetSplitViewOrientation()); + split_view_->set_divider_offset(GetSplitVievDividerOffset()); + split_view_->Layout(); + return true; + } + private: // views::View: virtual void Layout() OVERRIDE { @@ -86,9 +105,25 @@ class ContainerView : public views::View { } } + views::SingleSplitView::Orientation GetSplitViewOrientation() const { + if (dockside_ == "bottom") + return views::SingleSplitView::VERTICAL_SPLIT; + else + return views::SingleSplitView::HORIZONTAL_SPLIT; + } + + int GetSplitVievDividerOffset() const { + if (dockside_ == "bottom") + return height() * 2 / 3; + else + return width() * 2 / 3; + } + // True if the container view has already been created, or false otherwise. bool container_view_created_; + std::string dockside_; + scoped_ptr web_view_; scoped_ptr split_view_; views::WebView* devtools_view_; // Owned by split_view_. @@ -158,7 +193,7 @@ bool InspectableWebContentsViewWin::IsDevToolsViewShowing() { } bool InspectableWebContentsViewWin::SetDockSide(const std::string& side) { - return false; + return container_->SetDockSide(side); } } // namespace brightray From 9a70c9bb44be2d780047aa175240c208521e2372 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 12:35:23 +0800 Subject: [PATCH 7/8] Enable undocked devtools. --- .../win/inspectable_web_contents_view_win.cc | 79 +++++++++++-------- .../win/inspectable_web_contents_view_win.h | 2 +- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.cc b/brightray/browser/win/inspectable_web_contents_view_win.cc index 02fe15c0f534..24a52b658f7d 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.cc +++ b/brightray/browser/win/inspectable_web_contents_view_win.cc @@ -22,7 +22,7 @@ class ContainerView : public views::View { public: explicit ContainerView(InspectableWebContentsViewWin* web_contents_view) : container_view_created_(false), - dockside_("bottom"), + dockside_("none"), // "none" is treated as "bottom". web_view_(new views::WebView(NULL)), web_contents_view_(web_contents_view) { set_owned_by_client(); @@ -69,20 +69,18 @@ class ContainerView : public views::View { return split_view_; } - bool SetDockSide(const std::string& side) { - if (side != "bottom" && side != "right") - return false; // unsupported display location + void SetDockSide(const std::string& side) { if (dockside_ == side) - return true; // no change from current location + return; // no change from current location dockside_ = side; if (!IsDevToolsViewShowing()) - return true; + return; split_view_->set_orientation(GetSplitViewOrientation()); split_view_->set_divider_offset(GetSplitVievDividerOffset()); split_view_->Layout(); - return true; + return; } private: @@ -106,17 +104,17 @@ class ContainerView : public views::View { } views::SingleSplitView::Orientation GetSplitViewOrientation() const { - if (dockside_ == "bottom") - return views::SingleSplitView::VERTICAL_SPLIT; - else + if (dockside_ == "right") return views::SingleSplitView::HORIZONTAL_SPLIT; + else + return views::SingleSplitView::VERTICAL_SPLIT; } int GetSplitVievDividerOffset() const { - if (dockside_ == "bottom") - return height() * 2 / 3; - else + if (dockside_ == "right") return width() * 2 / 3; + else + return height() * 2 / 3; } // True if the container view has already been created, or false otherwise. @@ -139,6 +137,7 @@ InspectableWebContentsView* CreateInspectableContentsView( InspectableWebContentsViewWin::InspectableWebContentsViewWin( InspectableWebContentsImpl* inspectable_web_contents) : inspectable_web_contents_(inspectable_web_contents), + undocked_(false), container_(new ContainerView(this)) { } @@ -161,31 +160,30 @@ gfx::NativeView InspectableWebContentsViewWin::GetNativeView() const { } void InspectableWebContentsViewWin::ShowDevTools() { - container_->ShowDevTools(); - return; + if (undocked_) { + if (!devtools_window_) { + devtools_window_ = DevToolsWindow::Create(this)->AsWeakPtr(); + devtools_window_->Init(HWND_DESKTOP, gfx::Rect()); + } - if (!devtools_window_) { - devtools_window_ = DevToolsWindow::Create(this)->AsWeakPtr(); - devtools_window_->Init(HWND_DESKTOP, gfx::Rect()); + auto contents_view = inspectable_web_contents_->GetWebContents()->GetView(); + auto size = contents_view->GetContainerSize(); + size.Enlarge(-kWindowInset, -kWindowInset); + gfx::CenterAndSizeWindow(contents_view->GetNativeView(), + devtools_window_->hwnd(), + size); + + ShowWindow(devtools_window_->hwnd(), SW_SHOWNORMAL); + } else { + container_->ShowDevTools(); } - - auto contents_view = inspectable_web_contents_->GetWebContents()->GetView(); - auto size = contents_view->GetContainerSize(); - size.Enlarge(-kWindowInset, -kWindowInset); - gfx::CenterAndSizeWindow(contents_view->GetNativeView(), - devtools_window_->hwnd(), - size); - - ShowWindow(devtools_window_->hwnd(), SW_SHOWNORMAL); } void InspectableWebContentsViewWin::CloseDevTools() { - container_->CloseDevTools(); - return; - - if (!devtools_window_) - return; - SendMessage(devtools_window_->hwnd(), WM_CLOSE, 0, 0); + if (undocked_) + SendMessage(devtools_window_->hwnd(), WM_CLOSE, 0, 0); + else + container_->CloseDevTools(); } bool InspectableWebContentsViewWin::IsDevToolsViewShowing() { @@ -193,7 +191,20 @@ bool InspectableWebContentsViewWin::IsDevToolsViewShowing() { } bool InspectableWebContentsViewWin::SetDockSide(const std::string& side) { - return container_->SetDockSide(side); + if (side == "undocked") { + undocked_ = true; + container_->CloseDevTools(); + } else if (side == "right" || side == "bottom") { + undocked_ = false; + if (devtools_window_) + SendMessage(devtools_window_->hwnd(), WM_CLOSE, 0, 0); + container_->SetDockSide(side); + } else { + return false; + } + + ShowDevTools(); + return true; } } // namespace brightray diff --git a/brightray/browser/win/inspectable_web_contents_view_win.h b/brightray/browser/win/inspectable_web_contents_view_win.h index e7d288affda0..e55bbaac0902 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.h +++ b/brightray/browser/win/inspectable_web_contents_view_win.h @@ -40,8 +40,8 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { // Owns us. InspectableWebContentsImpl* inspectable_web_contents_; + bool undocked_; scoped_ptr container_; - base::WeakPtr devtools_window_; DISALLOW_COPY_AND_ASSIGN(InspectableWebContentsViewWin); From 1b274a1fd69d204bbfa63c8c3e4667a3b157bcde Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 10 Jun 2014 12:44:30 +0800 Subject: [PATCH 8/8] Add comments on the usage of attached devtools. --- .../browser/win/inspectable_web_contents_view_win.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/brightray/browser/win/inspectable_web_contents_view_win.h b/brightray/browser/win/inspectable_web_contents_view_win.h index e55bbaac0902..5f1321ae4181 100644 --- a/brightray/browser/win/inspectable_web_contents_view_win.h +++ b/brightray/browser/win/inspectable_web_contents_view_win.h @@ -23,7 +23,16 @@ class InspectableWebContentsViewWin : public InspectableWebContentsView { InspectableWebContentsImpl* inspectable_web_contents_impl); ~InspectableWebContentsViewWin(); + // Returns the container control, which has devtools view attached. Unlike + // GetNativeView(), this returns a views::View instead of HWND, and can only + // be used by applications that use the views library, if you don't use the + // views library, you probably want to set dock side to "undocked" before + // showing the devtools, because devtools is showed attached by default and + // attached devtools is currently only supported when using views library. views::View* GetView() const; + + // Returns the web view control, which can be used by the + // GetInitiallyFocusedView() to set initial focus to web view. views::View* GetWebView() const; virtual gfx::NativeView GetNativeView() const OVERRIDE;