chrome: Add Views API integration (see issue #2969)

The Chrome browser can now be hosted in a Views-based application on Windows
and Linux.

To launch a fully-featured Chrome window using cefsimple:
$ cefsimple --enable-chrome-runtime

To launch a minimally-styled Views-hosted window using cefsimple:
$ cefsimple --enable-chrome-runtime --use-views

To launch a fully-styled Views-hosted window using cefclient:
$ cefclient --enable-chrome-runtime --use-views

Views unit tests also now pass with the Chrome runtime enabled:
$ ceftests --gtest_filter=Views* --enable-chrome-runtime

Known issues:
- Popup browsers cannot be intercepted and reparented.
This commit is contained in:
Marshall Greenblatt 2021-02-17 20:58:25 -05:00
parent 8f5fdc1f9a
commit 8733cb89c7
31 changed files with 839 additions and 107 deletions

View File

@ -1061,10 +1061,14 @@ static_library("libcef_static") {
deps += [
"//ui/views",
]
}
if (use_aura) {
sources += [
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.cc",
"libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h",
"libcef/browser/chrome/views/chrome_browser_frame.cc",
"libcef/browser/chrome/views/chrome_browser_frame.h",
"libcef/browser/chrome/views/chrome_browser_view.cc",
"libcef/browser/chrome/views/chrome_browser_view.h",
"libcef/browser/native/window_delegate_view.cc",
"libcef/browser/native/window_delegate_view.h",
"libcef/browser/views/basic_label_button_impl.cc",

View File

@ -378,7 +378,7 @@ void AlloyBrowserHostImpl::SetFocusInternal(bool focus) {
}
CefWindowHandle AlloyBrowserHostImpl::GetWindowHandle() {
if (IsViewsHosted() && CEF_CURRENTLY_ON_UIT()) {
if (is_views_hosted_ && CEF_CURRENTLY_ON_UIT()) {
// Always return the most up-to-date window handle for a views-hosted
// browser since it may change if the view is re-parented.
if (platform_delegate_)
@ -391,10 +391,6 @@ CefWindowHandle AlloyBrowserHostImpl::GetOpenerWindowHandle() {
return opener_;
}
bool AlloyBrowserHostImpl::HasView() {
return IsViewsHosted();
}
double AlloyBrowserHostImpl::GetZoomLevel() {
// Verify that this method is being called on the UI thread.
if (!CEF_CURRENTLY_ON_UIT()) {
@ -803,10 +799,6 @@ bool AlloyBrowserHostImpl::IsWindowless() const {
return is_windowless_;
}
bool AlloyBrowserHostImpl::IsViewsHosted() const {
return is_views_hosted_;
}
bool AlloyBrowserHostImpl::IsPictureInPictureSupported() const {
// Not currently supported with OSR.
return !IsWindowless();
@ -870,22 +862,6 @@ void AlloyBrowserHostImpl::DestroyBrowser() {
CefBrowserHostBase::DestroyBrowser();
}
#if defined(USE_AURA)
views::Widget* AlloyBrowserHostImpl::GetWindowWidget() const {
CEF_REQUIRE_UIT();
if (!platform_delegate_)
return nullptr;
return platform_delegate_->GetWindowWidget();
}
CefRefPtr<CefBrowserView> AlloyBrowserHostImpl::GetBrowserView() const {
CEF_REQUIRE_UIT();
if (IsViewsHosted() && platform_delegate_)
return platform_delegate_->GetBrowserView();
return nullptr;
}
#endif
void AlloyBrowserHostImpl::CancelContextMenu() {
CEF_REQUIRE_UIT();
if (menu_manager_)
@ -1684,11 +1660,10 @@ AlloyBrowserHostImpl::AlloyBrowserHostImpl(
content::WebContentsObserver(web_contents),
opener_(kNullWindowHandle),
is_windowless_(platform_delegate_->IsWindowless()),
is_views_hosted_(platform_delegate_->IsViewsHosted()),
extension_(extension) {
contents_delegate_->ObserveWebContents(web_contents);
if (opener.get() && !platform_delegate_->IsViewsHosted()) {
if (opener.get() && !is_views_hosted_) {
// GetOpenerWindowHandle() only returns a value for non-views-hosted
// popup browsers.
opener_ = opener->GetWindowHandle();
@ -1707,7 +1682,7 @@ bool AlloyBrowserHostImpl::CreateHostWindow() {
bool success = true;
if (!IsWindowless())
success = platform_delegate_->CreateHostWindow();
if (success && !IsViewsHosted())
if (success && !is_views_hosted_)
host_window_handle_ = platform_delegate_->GetHostWindowHandle();
return success;
}

View File

@ -88,7 +88,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void SetFocus(bool focus) override;
CefWindowHandle GetWindowHandle() override;
CefWindowHandle GetOpenerWindowHandle() override;
bool HasView() override;
double GetZoomLevel() override;
void SetZoomLevel(double zoomLevel) override;
void RunFileDialog(FileDialogMode mode,
@ -161,14 +160,11 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// Returns true if windowless rendering is enabled.
bool IsWindowless() const;
// Returns true if this browser is views-hosted.
bool IsViewsHosted() const;
// Returns true if this browser supports picture-in-picture.
bool IsPictureInPictureSupported() const;
// Called when the OS window hosting the browser is destroyed.
void WindowDestroyed();
void WindowDestroyed() override;
// Destroy the browser members. This method should only be called after the
// native browser window is not longer processing messages.
@ -177,16 +173,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
// Cancel display of the context menu, if any.
void CancelContextMenu();
#if defined(USE_AURA)
// Returns the Widget owner for the browser window. Only used with windowed
// rendering.
views::Widget* GetWindowWidget() const;
// Returns the BrowserView associated with this browser. Only used with views-
// based browsers.
CefRefPtr<CefBrowserView> GetBrowserView() const;
#endif
bool MaybeAllowNavigation(content::RenderFrameHost* opener,
bool is_guest_view,
const content::OpenURLParams& params) override;
@ -374,7 +360,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
CefWindowHandle opener_;
const bool is_windowless_;
const bool is_views_hosted_;
CefWindowHandle host_window_handle_ = kNullWindowHandle;
CefRefPtr<CefExtension> extension_;
bool is_background_host_ = false;

View File

@ -163,7 +163,8 @@ CefBrowserHostBase::CefBrowserHostBase(
client_(client),
platform_delegate_(std::move(platform_delegate)),
browser_info_(browser_info),
request_context_(request_context) {
request_context_(request_context),
is_views_hosted_(platform_delegate_->IsViewsHosted()) {
CEF_REQUIRE_UIT();
DCHECK(!browser_info_->browser().get());
browser_info_->SetBrowser(this);
@ -205,6 +206,10 @@ CefRefPtr<CefRequestContext> CefBrowserHostBase::GetRequestContext() {
return request_context_;
}
bool CefBrowserHostBase::HasView() {
return is_views_hosted_;
}
void CefBrowserHostBase::StartDownload(const CefString& url) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
@ -790,3 +795,19 @@ content::BrowserContext* CefBrowserHostBase::GetBrowserContext() const {
return web_contents->GetBrowserContext();
return nullptr;
}
#if defined(TOOLKIT_VIEWS)
views::Widget* CefBrowserHostBase::GetWindowWidget() const {
CEF_REQUIRE_UIT();
if (!platform_delegate_)
return nullptr;
return platform_delegate_->GetWindowWidget();
}
CefRefPtr<CefBrowserView> CefBrowserHostBase::GetBrowserView() const {
CEF_REQUIRE_UIT();
if (is_views_hosted_ && platform_delegate_)
return platform_delegate_->GetBrowserView();
return nullptr;
}
#endif // defined(TOOLKIT_VIEWS)

View File

@ -38,6 +38,9 @@ struct CefBrowserCreateParams {
settings = that.settings;
request_context = that.request_context;
extra_info = that.extra_info;
#if defined(TOOLKIT_VIEWS)
browser_view = that.browser_view;
#endif
return *this;
}
@ -45,10 +48,9 @@ struct CefBrowserCreateParams {
// views-hosted browser. Currently used with the alloy runtime only.
std::unique_ptr<CefWindowInfo> window_info;
#if defined(USE_AURA)
// The BrowserView that will own a views-hosted browser. Will be nullptr for
#if defined(TOOLKIT_VIEWS)
// The BrowserView that will own a Views-hosted browser. Will be nullptr for
// popup browsers (the BrowserView will be created later in that case).
// Currently used with the alloy runtime only.
CefRefPtr<CefBrowserView> browser_view;
#endif
@ -100,6 +102,11 @@ class CefBrowserHostBase : public CefBrowserHost,
virtual ~Observer() {}
};
// Create a new CefBrowserHost instance of the current runtime type with
// owned WebContents.
static CefRefPtr<CefBrowserHostBase> Create(
CefBrowserCreateParams& create_params);
// Returns the browser associated with the specified RenderViewHost.
static CefRefPtr<CefBrowserHostBase> GetBrowserForHost(
const content::RenderViewHost* host);
@ -127,6 +134,10 @@ class CefBrowserHostBase : public CefBrowserHost,
// Called on the UI thread after the associated WebContents is created.
virtual void InitializeBrowser();
// Called on the UI thread when the OS window hosting the browser is
// destroyed.
virtual void WindowDestroyed() = 0;
// Called on the UI thread after the associated WebContents is destroyed.
// Also called from CefBrowserInfoManager::DestroyAllBrowsers if the browser
// was not properly shut down.
@ -136,6 +147,7 @@ class CefBrowserHostBase : public CefBrowserHost,
CefRefPtr<CefBrowser> GetBrowser() override;
CefRefPtr<CefClient> GetClient() override;
CefRefPtr<CefRequestContext> GetRequestContext() override;
bool HasView() override;
void StartDownload(const CefString& url) override;
void DownloadImage(const CefString& image_url,
bool is_favicon,
@ -221,6 +233,7 @@ class CefBrowserHostBase : public CefBrowserHost,
CefRefPtr<CefRequestContextImpl> request_context() const {
return request_context_;
}
bool is_views_hosted() const { return is_views_hosted_; }
// Accessors that must be called on the UI thread.
content::WebContents* GetWebContents() const;
@ -232,6 +245,16 @@ class CefBrowserHostBase : public CefBrowserHost,
return contents_delegate_.get();
}
#if defined(TOOLKIT_VIEWS)
// Returns the Widget owner for the browser window. Only used with windowed
// rendering.
views::Widget* GetWindowWidget() const;
// Returns the BrowserView associated with this browser. Only used with Views-
// based browsers.
CefRefPtr<CefBrowserView> GetBrowserView() const;
#endif
protected:
// Called from LoadMainFrameURL to perform the actual navigation.
virtual bool Navigate(const content::OpenURLParams& params);
@ -242,6 +265,7 @@ class CefBrowserHostBase : public CefBrowserHost,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate_;
scoped_refptr<CefBrowserInfo> browser_info_;
CefRefPtr<CefRequestContextImpl> request_context_;
const bool is_views_hosted_;
// Only accessed on the UI thread.
std::unique_ptr<CefBrowserContentsDelegate> contents_delegate_;

View File

@ -134,6 +134,12 @@ CefRefPtr<CefBrowser> CefBrowserHost::CreateBrowserSync(
create_params.extra_info = extra_info;
create_params.request_context = request_context;
return CefBrowserHostBase::Create(create_params);
}
// static
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::Create(
CefBrowserCreateParams& create_params) {
if (cef::IsChromeRuntimeEnabled()) {
auto browser = ChromeBrowserHostImpl::Create(create_params);
return browser.get();

View File

@ -112,7 +112,7 @@ CefWindowHandle CefBrowserPlatformDelegate::GetHostWindowHandle() const {
return kNullWindowHandle;
}
#if defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
views::Widget* CefBrowserPlatformDelegate::GetWindowWidget() const {
NOTREACHED();
return nullptr;
@ -122,7 +122,7 @@ CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
NOTREACHED();
return nullptr;
}
#endif
#endif // defined(TOOLKIT_VIEWS)
void CefBrowserPlatformDelegate::PopupWebContentsCreated(
const CefBrowserSettings& settings,

View File

@ -168,7 +168,7 @@ class CefBrowserPlatformDelegate {
// the client, which may be NULL. May be called on multiple threads.
virtual CefWindowHandle GetHostWindowHandle() const;
#if defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
// Returns the Widget owner for the browser window. Only used with windowed
// rendering.
virtual views::Widget* GetWindowWidget() const;

View File

@ -29,7 +29,8 @@
#error A delegate implementation is not available for your platform.
#endif
#if defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
#include "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "libcef/browser/views/browser_platform_delegate_views.h"
#endif
@ -82,6 +83,13 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
// CefWindowInfo is not used in this case.
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
CreateNativeDelegate(CefWindowInfo(), background_color);
#if defined(TOOLKIT_VIEWS)
if (create_params.browser_view) {
return std::make_unique<CefBrowserPlatformDelegateChromeViews>(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
}
#endif
return std::make_unique<CefBrowserPlatformDelegateChrome>(
std::move(native_delegate));
}
@ -113,7 +121,7 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
return std::make_unique<CefBrowserPlatformDelegateBackground>(
std::move(native_delegate));
}
#if defined(USE_AURA)
#if defined(TOOLKIT_VIEWS)
else {
// CefWindowInfo is not used in this case.
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate =
@ -122,7 +130,7 @@ std::unique_ptr<CefBrowserPlatformDelegate> CefBrowserPlatformDelegate::Create(
std::move(native_delegate),
static_cast<CefBrowserViewImpl*>(create_params.browser_view.get()));
}
#endif // defined(USE_AURA)
#endif // defined(TOOLKIT_VIEWS)
NOTREACHED();
return nullptr;

View File

@ -86,6 +86,11 @@ void CefBrowserPlatformDelegateChrome::ViewText(const std::string& text) {
native_delegate_->ViewText(text);
}
CefEventHandle CefBrowserPlatformDelegateChrome::GetEventHandle(
const content::NativeWebKeyboardEvent& event) const {
return native_delegate_->GetEventHandle(event);
}
CefWindowHandle CefBrowserPlatformDelegateChrome::GetParentWindowHandle()
const {
return GetHostWindowHandle();

View File

@ -36,6 +36,8 @@ class CefBrowserPlatformDelegateChrome
int deltaY) override;
gfx::Point GetScreenPoint(const gfx::Point& view) const override;
void ViewText(const std::string& text) override;
CefEventHandle GetEventHandle(
const content::NativeWebKeyboardEvent& event) const override;
// CefBrowserPlatformDelegateNative::WindowlessHandler methods:
CefWindowHandle GetParentWindowHandle() const override;
@ -43,7 +45,7 @@ class CefBrowserPlatformDelegateChrome
void set_chrome_browser(Browser* browser);
private:
protected:
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
Browser* chrome_browser_ = nullptr;

View File

@ -252,6 +252,11 @@ std::unique_ptr<BrowserDelegate> BrowserDelegate::Create(
cef_params.get());
if (params) {
create_params = params->create_params_;
// Clear these values so they're not persisted to additional Browsers.
#if defined(TOOLKIT_VIEWS)
params->create_params_.browser_view = nullptr;
#endif
}
return std::make_unique<ChromeBrowserDelegate>(browser, create_params);

View File

@ -7,6 +7,7 @@
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/features/runtime_checks.h"
#include "base/logging.h"
@ -22,6 +23,11 @@
#include "chrome/common/pref_names.h"
#include "url/url_constants.h"
#if defined(TOOLKIT_VIEWS)
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
#include "libcef/browser/chrome/views/chrome_browser_view.h"
#endif
// static
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
const CefBrowserCreateParams& params) {
@ -40,11 +46,46 @@ CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserHostImpl::Create(
// Pass |params| to cef::BrowserDelegate::Create from the Browser constructor.
chrome_params.cef_params = base::MakeRefCounted<DelegateCreateParams>(params);
#if defined(TOOLKIT_VIEWS)
// Configure Browser creation to use the existing Views-based
// Widget/BrowserFrame (ChromeBrowserFrame) and BrowserView/BrowserWindow
// (ChromeBrowserView). See views/chrome_browser_frame.h for related
// documentation.
ChromeBrowserView* chrome_browser_view = nullptr;
if (params.browser_view) {
// Don't show most controls.
chrome_params.type = Browser::TYPE_POPUP;
// Don't show title bar or address.
chrome_params.trusted_source = true;
auto view_impl =
static_cast<CefBrowserViewImpl*>(params.browser_view.get());
chrome_browser_view =
static_cast<ChromeBrowserView*>(view_impl->root_view());
chrome_params.window = chrome_browser_view;
auto chrome_widget =
static_cast<ChromeBrowserFrame*>(chrome_browser_view->GetWidget());
chrome_browser_view->set_frame(chrome_widget);
}
#endif // defined(TOOLKIT_VIEWS)
// Create the Browser. This will indirectly create the ChomeBrowserDelegate.
// The same params will be used to create a new Browser if the tab is dragged
// out of the existing Browser.
// out of the existing Browser. The returned Browser is owned by the
// associated BrowserView.
auto browser = Browser::Create(chrome_params);
#if defined(TOOLKIT_VIEWS)
if (chrome_browser_view) {
// Initialize the BrowserFrame and BrowserView and create the controls that
// require access to the Browser.
chrome_browser_view->InitBrowser(base::WrapUnique(browser),
params.browser_view);
}
#endif
GURL url = params.url;
if (url.is_empty()) {
// Chrome will navigate to kChromeUINewTabURL by default. We want to keep
@ -148,8 +189,9 @@ void ChromeBrowserHostImpl::CloseBrowser(bool force_close) {
}
bool ChromeBrowserHostImpl::TryCloseBrowser() {
NOTIMPLEMENTED();
return false;
// TODO(chrome): Handle the case where the browser may not close immediately.
CloseBrowser(true);
return true;
}
void ChromeBrowserHostImpl::SetFocus(bool focus) {
@ -168,11 +210,6 @@ CefWindowHandle ChromeBrowserHostImpl::GetOpenerWindowHandle() {
return kNullWindowHandle;
}
bool ChromeBrowserHostImpl::HasView() {
// TODO(chrome-runtime): Support Views-hosted browsers.
return false;
}
double ChromeBrowserHostImpl::GetZoomLevel() {
NOTIMPLEMENTED();
return 0.0;
@ -437,10 +474,10 @@ void ChromeBrowserHostImpl::Attach(Browser* browser,
DCHECK(browser);
DCHECK(web_contents);
SetBrowser(browser);
platform_delegate_->WebContentsCreated(web_contents,
/*own_web_contents=*/false);
SetBrowser(browser);
contents_delegate_->ObserveWebContents(web_contents);
InitializeBrowser();
}
@ -467,6 +504,19 @@ void ChromeBrowserHostImpl::InitializeBrowser() {
OnAfterCreated();
}
void ChromeBrowserHostImpl::WindowDestroyed() {
CEF_REQUIRE_UIT();
#if defined(TOOLKIT_VIEWS)
if (browser_ && is_views_hosted_) {
auto chrome_browser_view =
static_cast<ChromeBrowserView*>(browser_->window());
chrome_browser_view->Destroyed();
}
#endif
platform_delegate_->CloseHostWindow();
}
void ChromeBrowserHostImpl::DestroyBrowser() {
CEF_REQUIRE_UIT();
browser_ = nullptr;
@ -486,6 +536,8 @@ void ChromeBrowserHostImpl::DoCloseBrowser(bool force_close) {
// Like chrome::CloseTab() but specifying the WebContents.
const int tab_index = GetCurrentTabIndex();
if (tab_index != TabStripModel::kNoTab) {
// TODO(chrome): Handle the case where this method returns false,
// indicating that the contents were not closed immediately.
browser_->tab_strip_model()->CloseWebContentsAt(
tab_index, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB |
TabStripModel::CLOSE_USER_GESTURE);

View File

@ -66,7 +66,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
void SetFocus(bool focus) override;
CefWindowHandle GetWindowHandle() override;
CefWindowHandle GetOpenerWindowHandle() override;
bool HasView() override;
double GetZoomLevel() override;
void SetZoomLevel(double zoomLevel) override;
void RunFileDialog(FileDialogMode mode,
@ -160,6 +159,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
// CefBrowserHostBase methods:
void InitializeBrowser() override;
void WindowDestroyed() override;
void DestroyBrowser() override;
void DoCloseBrowser(bool force_close);

View File

@ -0,0 +1,64 @@
// Copyright 2021 The Chromium Embedded Framework 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 "libcef/browser/chrome/views/browser_platform_delegate_chrome_views.h"
#include "chrome/browser/ui/browser.h"
#include "ui/views/widget/widget.h"
CefBrowserPlatformDelegateChromeViews::CefBrowserPlatformDelegateChromeViews(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view)
: CefBrowserPlatformDelegateChrome(std::move(native_delegate)),
browser_view_(browser_view) {}
void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
content::WebContents* web_contents,
bool owned) {
CefBrowserPlatformDelegateChrome::WebContentsCreated(web_contents, owned);
browser_view_->WebContentsCreated(web_contents);
}
void CefBrowserPlatformDelegateChromeViews::BrowserCreated(
CefBrowserHostBase* browser) {
CefBrowserPlatformDelegateChrome::BrowserCreated(browser);
browser_view_->BrowserCreated(browser, base::RepeatingClosure());
}
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserCreated() {
if (browser_view_->delegate())
browser_view_->delegate()->OnBrowserCreated(browser_view_, browser_);
}
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserDestroyed() {
if (browser_view_->delegate())
browser_view_->delegate()->OnBrowserDestroyed(browser_view_, browser_);
}
void CefBrowserPlatformDelegateChromeViews::BrowserDestroyed(
CefBrowserHostBase* browser) {
CefBrowserPlatformDelegateChrome::BrowserDestroyed(browser);
browser_view_->BrowserDestroyed(browser);
}
void CefBrowserPlatformDelegateChromeViews::CloseHostWindow() {
views::Widget* widget = GetWindowWidget();
if (widget && !widget->IsClosed())
widget->Close();
}
views::Widget* CefBrowserPlatformDelegateChromeViews::GetWindowWidget() const {
if (browser_view_->root_view())
return browser_view_->root_view()->GetWidget();
return nullptr;
}
CefRefPtr<CefBrowserView>
CefBrowserPlatformDelegateChromeViews::GetBrowserView() const {
return browser_view_.get();
}
bool CefBrowserPlatformDelegateChromeViews::IsViewsHosted() const {
return true;
}

View File

@ -0,0 +1,35 @@
// Copyright 2021 The Chromium Embedded Framework 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 CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
#include "libcef/browser/chrome/browser_platform_delegate_chrome.h"
#include "libcef/browser/views/browser_view_impl.h"
// Implementation of Chrome-based browser functionality.
class CefBrowserPlatformDelegateChromeViews
: public CefBrowserPlatformDelegateChrome {
public:
explicit CefBrowserPlatformDelegateChromeViews(
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate,
CefRefPtr<CefBrowserViewImpl> browser_view);
// CefBrowserPlatformDelegate overrides.
void WebContentsCreated(content::WebContents* web_contents,
bool owned) override;
void BrowserCreated(CefBrowserHostBase* browser) override;
void NotifyBrowserCreated() override;
void NotifyBrowserDestroyed() override;
void BrowserDestroyed(CefBrowserHostBase* browser) override;
void CloseHostWindow() override;
views::Widget* GetWindowWidget() const override;
CefRefPtr<CefBrowserView> GetBrowserView() const override;
bool IsViewsHosted() const override;
private:
CefRefPtr<CefBrowserViewImpl> browser_view_;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_

View File

@ -0,0 +1,35 @@
// Copyright 2021 The Chromium Embedded Framework 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 "libcef/browser/chrome/views/chrome_browser_frame.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
void ChromeBrowserFrame::Init(BrowserView* browser_view,
std::unique_ptr<Browser> browser) {
DCHECK(browser_view);
DCHECK(!browser_);
browser_ = browser.get();
DCHECK(browser_);
// Initialize BrowserFrame state.
InitBrowserView(browser_view);
// Initialize BrowserView state.
browser_view->InitBrowser(std::move(browser));
}
views::internal::RootView* ChromeBrowserFrame::CreateRootView() {
// Bypass the BrowserFrame implementation.
return views::Widget::CreateRootView();
}
std::unique_ptr<views::NonClientFrameView>
ChromeBrowserFrame::CreateNonClientFrameView() {
// Bypass the BrowserFrame implementation.
return views::Widget::CreateNonClientFrameView();
}

View File

@ -0,0 +1,109 @@
// Copyright 2021 The Chromium Embedded Framework 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 CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_FRAME_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_FRAME_H_
#pragma once
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
// An overview of the Chrome Browser object model is provided below. Object
// creation normally begins with a call to Browser::Create(CreateParams) which
// then creates the necessary Browser view, window and frame objects. CEF has
// modified the default object creation model are described below to better
// integrate with the existing CEF Views APIs.
//
// OVERVIEW
//
// Browser and BrowserWindow are the primary Chrome objects. Browser provides
// the concrete state and mutation methods while BrowserWindow is an interface
// implemented by the platform-specific "view" of the Browser window.
//
// Browser:
// - Creates a BrowserView (aka BrowserWindow) and BrowserFrame (aka Widget) via
// a call to BrowserWindow::CreateBrowserWindow() in the Browser constructor.
// - An existing BrowserWindow can alternately be specified via the
// Browser::CreateParams::window parameter.
// - Owned by the BrowserView after creation.
//
// The Chrome Views implementation uses BrowserView to represent the browser
// client area and BrowserFrame (plus helpers) to represent the non-client
// window frame.
//
// BrowserView:
// - Extends BrowserWindow, views::ClientView, views::WidgetDelegate.
// - Owns the Browser.
// - References the BrowserFrame.
// - Passed to Widget::Init() via Widget::InitParams::delegate to receive
// WidgetDelegate callbacks.
// - Extended by CEF as ChromeBrowserView.
// BrowserFrame:
// - Extends Widget (aka views::internal::NativeWidgetDelegate).
// - References the BrowserView.
// - Creates/owns a DesktopBrowserFrameAura (aka NativeBrowserFrame) via
// BrowserFrame::InitBrowserFrame().
// - Extended by CEF as ChromeBrowserFrame.
//
// Chrome custom window/frame handling is implemented using platform-specific
// objects.
//
// DesktopBrowserFrameAura:
// - Extends NativeBrowserFrame, DesktopNativeWidgetAura.
// - Acts as a helper for BrowserFrame.
// - Creates/references a BrowserDesktopWindowTreeHostWin via
// DesktopBrowserFrameAura::InitNativeWidget().
// BrowserDesktopWindowTreeHostWin (for Windows):
// - Extends DesktopWindowTreeHost.
// - References DesktopBrowserFrameAura, BrowserView, BrowserFrame.
// - Passed to Widget::Init() via Widget::InitParams::desktop_window_tree_host.
//
// CEF MODIFICATIONS
//
// The CEF Views integration uses an alternative approach of creating the
// ChromeBrowserFrame in CefWindowView::CreateWidget() and the
// ChromeBrowserView in CefBrowserViewImpl::CreateRootView().
// The object associations described above are then configured via
// ChromeBrowserView::AddedToWidget() and ChromeBrowserHostImpl::Create()
// after the BrowserView is added to the Widget. The Chromium code has been
// patched to allow later initialization of the Browser, BrowserFrame and
// BrowserView members to support this model.
//
// CEF does not use Chrome's NativeBrowserFrame (aka DesktopBrowserFrameAura),
// BrowserNonClientFrameView or BrowserRootView objects (all normally created by
// BrowserFrame during Widget initialization). Consequently
// |BrowserFrame::native_browser_frame_| and |BrowserFrame::browser_frame_view_|
// (sometimes retrieved via BrowserFrame::GetFrameView) will be nullptr and the
// Chromium code has been patched to add the necessary null checks.
//
// CEF does not pass ChromeBrowserView as the WidgetDelegate when the Widget is
// initialized in CefWindowView::CreateWidget(). Some of the WidgetDelegate
// callbacks may need to be routed from CefWindowView to ChromeBrowserView in
// the future.
//
// See the chrome_runtime_views.patch file for the complete set of related
// modifications.
class BrowserView;
// Widget for a Views-hosted Chrome browser. Created in
// CefWindowView::CreateWidget() when the Chrome runtime is enabled.
class ChromeBrowserFrame : public BrowserFrame {
public:
ChromeBrowserFrame() {}
ChromeBrowserFrame(const ChromeBrowserFrame&) = delete;
ChromeBrowserFrame& operator=(const ChromeBrowserFrame&) = delete;
void Init(BrowserView* browser_view, std::unique_ptr<Browser> browser);
// views::Widget methods:
views::internal::RootView* CreateRootView() override;
std::unique_ptr<views::NonClientFrameView> CreateNonClientFrameView()
override;
private:
Browser* browser_ = nullptr;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_FRAME_H_

View File

@ -0,0 +1,70 @@
// Copyright 2021 The Chromium Embedded Framework 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 "libcef/browser/chrome/views/chrome_browser_view.h"
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
#include "libcef/browser/views/browser_view_impl.h"
ChromeBrowserView::ChromeBrowserView(CefBrowserViewDelegate* cef_delegate,
Delegate* browser_view_delegate)
: ParentClass(cef_delegate), browser_view_delegate_(browser_view_delegate) {
DCHECK(browser_view_delegate_);
}
void ChromeBrowserView::InitBrowser(std::unique_ptr<Browser> browser,
CefRefPtr<CefBrowserView> browser_view) {
DCHECK(!browser_);
DCHECK(!web_view_);
browser_ = browser.get();
DCHECK(browser_);
// Initialize the BrowserFrame and BrowserView.
auto chrome_widget = static_cast<ChromeBrowserFrame*>(GetWidget());
chrome_widget->Init(this, std::move(browser));
// Retrieve the views::WebView that was created by the above initializations.
auto view_impl = static_cast<CefBrowserViewImpl*>(browser_view.get());
web_view_ = view_impl->web_view();
DCHECK(web_view_);
ParentClass::AddedToWidget();
}
void ChromeBrowserView::Destroyed() {
DCHECK(!destroyed_);
destroyed_ = true;
browser_ = nullptr;
web_view_ = nullptr;
}
void ChromeBrowserView::ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) {
ParentClass::ViewHierarchyChanged(details);
if (details.is_add && details.child == this) {
gfx::Size size = GetPreferredSize();
if (size.IsEmpty()) {
// No size was provided for this View. Size it to the parent by default
// or, depending on the Layout, the browser may be initially 0x0 size and
// will not display until the parent is next resized (resulting in a call
// to WebView::OnBoundsChanged). For example, this can happen when adding
// this View to a CefWindow with FillLayout and then calling
// CefWindow::Show() without first resizing the CefWindow.
size = details.parent->GetPreferredSize();
if (!size.IsEmpty())
SetSize(size);
}
}
}
void ChromeBrowserView::AddedToWidget() {
// Results in a call to InitBrowser which calls ParentClass::AddedToWidget.
browser_view_delegate_->OnBrowserViewAdded();
}
void ChromeBrowserView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
ParentClass::OnBoundsChanged(previous_bounds);
browser_view_delegate_->OnBoundsChanged();
}

View File

@ -0,0 +1,57 @@
// Copyright 2021 The Chromium Embedded Framework 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 CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_VIEW_H_
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_VIEW_H_
#pragma once
#include "include/views/cef_browser_view.h"
#include "include/views/cef_browser_view_delegate.h"
#include "libcef/browser/views/browser_view_view.h"
#include "libcef/browser/views/view_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
namespace views {
class WebView;
} // namespace views
// A variant of CefBrowserViewView that extends BrowserView instead of
// views::WebView. See chrome_browser_frame.h for related documentation.
class ChromeBrowserView
: public CefViewView<BrowserView, CefBrowserViewDelegate> {
public:
using ParentClass = CefViewView<BrowserView, CefBrowserViewDelegate>;
using Delegate = CefBrowserViewView::Delegate;
// |cef_delegate| may be nullptr.
// |browser_view_delegate| must be non-nullptr.
ChromeBrowserView(CefBrowserViewDelegate* cef_delegate,
Delegate* browser_view_delegate);
// Called by ChromeBrowserHostImpl.
void InitBrowser(std::unique_ptr<Browser> browser,
CefRefPtr<CefBrowserView> browser_view);
void Destroyed();
// View methods:
void ViewHierarchyChanged(
const views::ViewHierarchyChangedDetails& details) override;
void AddedToWidget() override;
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
private:
// Not owned by this object.
Delegate* browser_view_delegate_;
Browser* browser_ = nullptr;
views::WebView* web_view_ = nullptr;
bool destroyed_ = false;
DISALLOW_COPY_AND_ASSIGN(ChromeBrowserView);
};
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_CHROME_BROWSER_VIEW_H_

View File

@ -251,7 +251,7 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show(
}
CefBrowserCreateParams create_params;
if (!inspected_browser->IsViewsHosted())
if (!inspected_browser->is_views_hosted())
create_params.window_info.reset(new CefWindowInfo(windowInfo));
create_params.client = client;
create_params.settings = new_settings;

View File

@ -388,7 +388,7 @@ base::DictionaryValue* CefExtensionFunctionDetails::OpenTab(
return nullptr;
}
if (active_browser->IsViewsHosted()) {
if (active_browser->is_views_hosted()) {
// The new browser will also be Views hosted.
create_params.window_info.reset();
}

View File

@ -4,11 +4,13 @@
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_util.h"
#include "libcef/browser/chrome/views/chrome_browser_view.h"
#include "libcef/browser/context.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/window_impl.h"
#include "libcef/features/runtime.h"
#include "libcef/features/runtime_checks.h"
#include "content/public/browser/native_web_keyboard_event.h"
@ -29,12 +31,11 @@ CefRefPtr<CefBrowserView> CefBrowserView::CreateBrowserView(
// static
CefRefPtr<CefBrowserView> CefBrowserView::GetForBrowser(
CefRefPtr<CefBrowser> browser) {
REQUIRE_ALLOY_RUNTIME();
CEF_REQUIRE_UIT_RETURN(nullptr);
AlloyBrowserHostImpl* browser_impl =
static_cast<AlloyBrowserHostImpl*>(browser.get());
if (browser_impl && browser_impl->IsViewsHosted())
CefBrowserHostBase* browser_impl =
static_cast<CefBrowserHostBase*>(browser.get());
if (browser_impl && browser_impl->is_views_hosted())
return browser_impl->GetBrowserView();
return nullptr;
}
@ -47,7 +48,6 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
CefRefPtr<CefDictionaryValue> extra_info,
CefRefPtr<CefRequestContext> request_context,
CefRefPtr<CefBrowserViewDelegate> delegate) {
REQUIRE_ALLOY_RUNTIME();
CEF_REQUIRE_UIT_RETURN(nullptr);
CefRefPtr<CefBrowserViewImpl> browser_view = new CefBrowserViewImpl(delegate);
@ -73,8 +73,8 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::CreateForPopup(
void CefBrowserViewImpl::WebContentsCreated(
content::WebContents* web_contents) {
if (root_view())
root_view()->SetWebContents(web_contents);
if (web_view())
web_view()->SetWebContents(web_contents);
}
void CefBrowserViewImpl::BrowserCreated(
@ -88,8 +88,8 @@ void CefBrowserViewImpl::BrowserDestroyed(CefBrowserHostBase* browser) {
DCHECK_EQ(browser, browser_);
browser_ = nullptr;
if (root_view())
root_view()->SetWebContents(nullptr);
if (web_view())
web_view()->SetWebContents(nullptr);
}
bool CefBrowserViewImpl::HandleKeyboardEvent(
@ -128,8 +128,8 @@ CefRefPtr<CefBrowser> CefBrowserViewImpl::GetBrowser() {
void CefBrowserViewImpl::SetPreferAccelerators(bool prefer_accelerators) {
CEF_REQUIRE_VALID_RETURN_VOID();
if (root_view())
root_view()->set_allow_accelerators(prefer_accelerators);
if (web_view())
web_view()->set_allow_accelerators(prefer_accelerators);
}
void CefBrowserViewImpl::RequestFocus() {
@ -143,8 +143,8 @@ void CefBrowserViewImpl::RequestFocus() {
void CefBrowserViewImpl::SetBackgroundColor(cef_color_t color) {
CEF_REQUIRE_VALID_RETURN_VOID();
ParentClass::SetBackgroundColor(color);
if (root_view())
root_view()->SetResizeBackgroundColor(color);
if (web_view())
web_view()->SetResizeBackgroundColor(color);
}
void CefBrowserViewImpl::Detach() {
@ -154,12 +154,12 @@ void CefBrowserViewImpl::Detach() {
DCHECK(!root_view());
if (browser_) {
// |browser_| will disappear when WindowDestroyed() indirectly calls
// BrowserDestroyed() so keep a reference.
// With the Alloy runtime |browser_| will disappear when WindowDestroyed()
// indirectly calls BrowserDestroyed() so keep a reference.
CefRefPtr<CefBrowserHostBase> browser = browser_;
// Force the browser to be destroyed.
static_cast<AlloyBrowserHostImpl*>(browser.get())->WindowDestroyed();
browser->WindowDestroyed();
}
}
@ -176,7 +176,7 @@ void CefBrowserViewImpl::OnBrowserViewAdded() {
// hierarchy.
pending_browser_create_params_->browser_view = this;
AlloyBrowserHostImpl::Create(*pending_browser_create_params_);
CefBrowserHostBase::Create(*pending_browser_create_params_);
DCHECK(browser_);
pending_browser_create_params_.reset(nullptr);
@ -212,12 +212,28 @@ void CefBrowserViewImpl::SetDefaults(const CefBrowserSettings& settings) {
CefContext::Get()->GetBackgroundColor(&settings, STATE_DISABLED));
}
CefBrowserViewView* CefBrowserViewImpl::CreateRootView() {
views::View* CefBrowserViewImpl::CreateRootView() {
if (cef::IsChromeRuntimeEnabled()) {
return new ChromeBrowserView(delegate(), this);
}
return new CefBrowserViewView(delegate(), this);
}
void CefBrowserViewImpl::InitializeRootView() {
static_cast<CefBrowserViewView*>(root_view())->Initialize();
if (cef::IsChromeRuntimeEnabled()) {
static_cast<ChromeBrowserView*>(root_view())->Initialize();
} else {
static_cast<CefBrowserViewView*>(root_view())->Initialize();
}
}
views::WebView* CefBrowserViewImpl::web_view() const {
if (cef::IsChromeRuntimeEnabled()) {
return static_cast<ChromeBrowserView*>(root_view())->contents_web_view();
}
return static_cast<CefBrowserViewView*>(root_view());
}
bool CefBrowserViewImpl::HandleAccelerator(

View File

@ -19,14 +19,11 @@
class CefBrowserHostBase;
class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
CefBrowserView,
CefBrowserViewDelegate>,
public CefBrowserViewView::Delegate {
class CefBrowserViewImpl
: public CefViewImpl<views::View, CefBrowserView, CefBrowserViewDelegate>,
public CefBrowserViewView::Delegate {
public:
typedef CefViewImpl<CefBrowserViewView,
CefBrowserView,
CefBrowserViewDelegate>
typedef CefViewImpl<views::View, CefBrowserView, CefBrowserViewDelegate>
ParentClass;
// Create a new CefBrowserView instance. |delegate| may be nullptr.
@ -73,6 +70,9 @@ class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
void OnBrowserViewAdded() override;
void OnBoundsChanged() override;
// Return the WebView representation of this object.
views::WebView* web_view() const;
private:
// Create a new implementation object.
// Always call Initialize() after creation.
@ -89,7 +89,7 @@ class CefBrowserViewImpl : public CefViewImpl<CefBrowserViewView,
void SetDefaults(const CefBrowserSettings& settings);
// CefViewImpl methods:
CefBrowserViewView* CreateRootView() override;
views::View* CreateRootView() override;
void InitializeRootView() override;
// Logic extracted from UnhandledKeyboardEventHandler::HandleKeyboardEvent for

View File

@ -4,8 +4,10 @@
#include "libcef/browser/views/window_view.h"
#include "libcef/browser/chrome/views/chrome_browser_frame.h"
#include "libcef/browser/image_impl.h"
#include "libcef/browser/views/window_impl.h"
#include "libcef/features/runtime.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/aura/window.h"
@ -248,7 +250,8 @@ void CefWindowView::CreateWidget() {
// |widget| is owned by the NativeWidget and will be destroyed in response to
// a native destruction message.
views::Widget* widget = new views::Widget;
views::Widget* widget = cef::IsChromeRuntimeEnabled() ? new ChromeBrowserFrame
: new views::Widget;
views::Widget::InitParams params;
params.delegate = this;

View File

@ -206,6 +206,13 @@ patches = [
# https://bitbucket.org/chromiumembedded/cef/issues/2969
'name': 'chrome_runtime',
},
{
# Changes to support Chrome runtime integration with CEF Views.
# See related documentation in
# libcef/browser/chrome/views/chrome_browser_frame.h.
# https://bitbucket.org/chromiumembedded/cef/issues/2969
'name': 'chrome_runtime_views',
},
{
# Changes to support the Chrome runtime in CEF.
# https://bitbucket.org/chromiumembedded/cef/issues/2969

View File

@ -0,0 +1,233 @@
diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc
index 5c03f250e500..ecfce9c2c7c7 100644
--- chrome/browser/ui/views/frame/browser_frame.cc
+++ chrome/browser/ui/views/frame/browser_frame.cc
@@ -63,15 +63,23 @@ bool IsUsingGtkTheme(Profile* profile) {
////////////////////////////////////////////////////////////////////////////////
// BrowserFrame, public:
+BrowserFrame::BrowserFrame() : BrowserFrame(nullptr) {}
+
BrowserFrame::BrowserFrame(BrowserView* browser_view)
: native_browser_frame_(nullptr),
root_view_(nullptr),
browser_frame_view_(nullptr),
- browser_view_(browser_view) {
- browser_view_->set_frame(this);
+ browser_view_(nullptr) {
set_is_secondary_widget(false);
// Don't focus anything on creation, selecting a tab will set the focus.
set_focus_on_creation(false);
+ if (browser_view)
+ InitBrowserView(browser_view);
+}
+
+void BrowserFrame::InitBrowserView(BrowserView* browser_view) {
+ browser_view_ = browser_view;
+ browser_view_->set_frame(this);
}
BrowserFrame::~BrowserFrame() {}
@@ -133,6 +141,12 @@ gfx::Rect BrowserFrame::GetBoundsForTabStripRegion(
}
int BrowserFrame::GetTopInset() const {
+ if (!browser_frame_view_) {
+ // With CEF the browser may already be part of a larger Views layout. Zero
+ // out the adjustment in BrowserView::GetTopInsetInBrowserView() so that
+ // the browser isn't shifted to the top of the window.
+ return browser_view_->y();
+ }
return browser_frame_view_->GetTopInset(false);
}
@@ -167,15 +181,21 @@ void BrowserFrame::GetWindowPlacement(gfx::Rect* bounds,
content::KeyboardEventProcessingResult BrowserFrame::PreHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
+ if (!native_browser_frame_)
+ return content::KeyboardEventProcessingResult::NOT_HANDLED;
return native_browser_frame_->PreHandleKeyboardEvent(event);
}
bool BrowserFrame::HandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
+ if (!native_browser_frame_)
+ return false;
return native_browser_frame_->HandleKeyboardEvent(event);
}
void BrowserFrame::OnBrowserViewInitViewsComplete() {
+ if (!browser_frame_view_)
+ return;
browser_frame_view_->OnBrowserViewInitViewsComplete();
}
@@ -208,7 +228,8 @@ const ui::ThemeProvider* BrowserFrame::GetThemeProvider() const {
}
const ui::NativeTheme* BrowserFrame::GetNativeTheme() const {
- if (browser_view_->browser()->profile()->IsIncognitoProfile() &&
+ if (browser_view_ &&
+ browser_view_->browser()->profile()->IsIncognitoProfile() &&
ThemeServiceFactory::GetForProfile(browser_view_->browser()->profile())
->UsingDefaultTheme()) {
return ui::NativeTheme::GetInstanceForDarkUI();
diff --git chrome/browser/ui/views/frame/browser_frame.h chrome/browser/ui/views/frame/browser_frame.h
index 3a1314f21ce4..f9464abc97a7 100644
--- chrome/browser/ui/views/frame/browser_frame.h
+++ chrome/browser/ui/views/frame/browser_frame.h
@@ -53,7 +53,9 @@ enum class TabDragKind {
// This is a virtual interface that allows system specific browser frames.
class BrowserFrame : public views::Widget, public views::ContextMenuController {
public:
+ BrowserFrame();
explicit BrowserFrame(BrowserView* browser_view);
+ void InitBrowserView(BrowserView* browser_view);
~BrowserFrame() override;
// Initialize the frame (creates the underlying native window).
diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
index c4d99326bacf..3c7b45b99186 100644
--- chrome/browser/ui/views/frame/browser_view.cc
+++ chrome/browser/ui/views/frame/browser_view.cc
@@ -545,16 +545,26 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
// static
const char BrowserView::kViewClassName[] = "BrowserView";
+BrowserView::BrowserView() : BrowserView(nullptr) {}
+
BrowserView::BrowserView(std::unique_ptr<Browser> browser)
: views::ClientView(nullptr, nullptr),
- browser_(std::move(browser)),
accessibility_mode_observer_(
std::make_unique<AccessibilityModeObserver>(this)) {
+ if (browser)
+ InitBrowser(std::move(browser));
+}
+
+void BrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
+ DCHECK(!browser_);
+ browser_ = std::move(browser);
+
+ immersive_mode_controller_ = chrome::CreateImmersiveModeController();
+
SetShowIcon(::ShouldShowWindowIcon(browser_.get()));
SetHasWindowSizeControls(!chrome::IsRunningInForcedAppMode());
browser_->tab_strip_model()->AddObserver(this);
- immersive_mode_controller_ = chrome::CreateImmersiveModeController();
// Top container holds tab strip region and toolbar and lives at the front of
// the view hierarchy.
@@ -1340,6 +1350,8 @@ bool BrowserView::ShouldHideUIForFullscreen() const {
if (immersive_mode_controller_->IsEnabled())
return false;
+ if (!frame_->GetFrameView())
+ return false;
return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
}
@@ -2357,7 +2369,8 @@ BrowserView::GetNativeViewHostsForTopControlsSlide() const {
}
void BrowserView::ReparentTopContainerForEndOfImmersive() {
- overlay_view_->SetVisible(false);
+ if (overlay_view_)
+ overlay_view_->SetVisible(false);
top_container()->DestroyLayer();
AddChildViewAt(top_container(), 0);
EnsureFocusOrder();
@@ -2804,7 +2817,8 @@ void BrowserView::Layout() {
// TODO(jamescook): Why was this in the middle of layout code?
toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
IsToolbarVisible() ? FocusBehavior::ALWAYS : FocusBehavior::NEVER);
- frame()->GetFrameView()->UpdateMinimumSize();
+ if (frame()->GetFrameView())
+ frame()->GetFrameView()->UpdateMinimumSize();
// Some of the situations when the BrowserView is laid out are:
// - Enter/exit immersive fullscreen mode.
@@ -2907,7 +2921,8 @@ void BrowserView::AddedToWidget() {
SetToolbarButtonProvider(toolbar_);
frame_->OnBrowserViewInitViewsComplete();
- frame_->GetFrameView()->UpdateMinimumSize();
+ if (frame_->GetFrameView())
+ frame_->GetFrameView()->UpdateMinimumSize();
using_native_frame_ = frame_->ShouldUseNativeFrame();
MaybeInitializeWebUITabStrip();
diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
index 986798357dbc..2793bf7b184e 100644
--- chrome/browser/ui/views/frame/browser_view.h
+++ chrome/browser/ui/views/frame/browser_view.h
@@ -117,7 +117,9 @@ class BrowserView : public BrowserWindow,
// The browser view's class name.
static const char kViewClassName[];
+ BrowserView();
explicit BrowserView(std::unique_ptr<Browser> browser);
+ void InitBrowser(std::unique_ptr<Browser> browser);
~BrowserView() override;
void set_frame(BrowserFrame* frame) { frame_ = frame; }
diff --git chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index 824acb2c7c8a..cd81e0e3f4d3 100644
--- chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -578,37 +578,53 @@ gfx::Range BrowserTabStripController::ListTabsInGroup(
}
bool BrowserTabStripController::IsFrameCondensed() const {
+ if (!GetFrameView())
+ return false;
return GetFrameView()->IsFrameCondensed();
}
bool BrowserTabStripController::HasVisibleBackgroundTabShapes() const {
+ if (!GetFrameView())
+ return false;
return GetFrameView()->HasVisibleBackgroundTabShapes(
BrowserFrameActiveState::kUseCurrent);
}
bool BrowserTabStripController::EverHasVisibleBackgroundTabShapes() const {
+ if (!GetFrameView())
+ return false;
return GetFrameView()->EverHasVisibleBackgroundTabShapes();
}
bool BrowserTabStripController::ShouldPaintAsActiveFrame() const {
+ if (!GetFrameView())
+ return false;
return GetFrameView()->ShouldPaintAsActive();
}
bool BrowserTabStripController::CanDrawStrokes() const {
+ if (!GetFrameView())
+ return false;
return GetFrameView()->CanDrawStrokes();
}
SkColor BrowserTabStripController::GetFrameColor(
BrowserFrameActiveState active_state) const {
+ if (!GetFrameView())
+ return SK_ColorWHITE;
return GetFrameView()->GetFrameColor(active_state);
}
SkColor BrowserTabStripController::GetToolbarTopSeparatorColor() const {
+ if (!GetFrameView())
+ return SK_ColorWHITE;
return GetFrameView()->GetToolbarTopSeparatorColor();
}
base::Optional<int> BrowserTabStripController::GetCustomBackgroundId(
BrowserFrameActiveState active_state) const {
+ if (!GetFrameView())
+ return base::nullopt;
return GetFrameView()->GetCustomBackgroundId(active_state);
}

View File

@ -93,6 +93,16 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
#endif
}
// Enable experimental Chrome runtime. See issue #2969 for details.
use_chrome_runtime_ =
command_line_->HasSwitch(switches::kEnableChromeRuntime);
if (use_windowless_rendering_ && use_chrome_runtime_) {
LOG(ERROR)
<< "Windowless rendering is not supported with the Chrome runtime.";
use_chrome_runtime_ = false;
}
#if defined(OS_WIN) || defined(OS_LINUX)
// Whether the Views framework will be used.
use_views_ = command_line_->HasSwitch(switches::kUseViews);
@ -103,6 +113,14 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
use_views_ = false;
}
if (use_chrome_runtime_ && !use_views_) {
// TODO(chrome): Add support for this runtime configuration (e.g. a fully
// styled Chrome window with cefclient menu customizations). In the mean
// time this can be demo'd with "cefsimple --enable-chrome-runtime".
LOG(WARNING) << "Chrome runtime requires the Views framework.";
use_views_ = true;
}
if (use_views_ && command_line->HasSwitch(switches::kHideFrame) &&
!command_line_->HasSwitch(switches::kUrl)) {
// Use the draggable regions test as the default URL for frameless windows.
@ -178,6 +196,9 @@ void MainContextImpl::PopulateSettings(CefSettings* settings) {
command_line_->HasSwitch(switches::kExternalMessagePump);
}
if (use_chrome_runtime_)
settings->chrome_runtime = true;
CefString(&settings->cache_path) =
command_line_->GetSwitchValue(switches::kCachePath);

View File

@ -70,6 +70,7 @@ class MainContextImpl : public MainContext {
cef_color_t browser_background_color_;
bool use_windowless_rendering_;
int windowless_frame_rate_;
bool use_chrome_runtime_;
bool use_views_;
bool touch_events_enabled_;

View File

@ -85,8 +85,6 @@ void SimpleApp::OnContextInitialized() {
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool enable_chrome_runtime = SimpleHandler::IsChromeRuntimeEnabled();
#if defined(OS_WIN) || defined(OS_LINUX)
// Create the browser using the Views framework if "--use-views" is specified
// via the command-line. Otherwise, create the browser using the native
@ -111,7 +109,7 @@ void SimpleApp::OnContextInitialized() {
if (url.empty())
url = "http://www.google.com";
if (use_views && !enable_chrome_runtime) {
if (use_views) {
// Create the BrowserView.
CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
handler, url, browser_settings, nullptr, nullptr,

View File

@ -47,10 +47,6 @@ void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
const CefString& title) {
CEF_REQUIRE_UI_THREAD();
// Allow Chrome to handle the title change.
if (IsChromeRuntimeEnabled())
return;
if (use_views_) {
// Set the title of the window using the Views framework.
CefRefPtr<CefBrowserView> browser_view =
@ -60,7 +56,7 @@ void SimpleHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
if (window)
window->SetTitle(title);
}
} else {
} else if (!IsChromeRuntimeEnabled()) {
// Set the title of the window using platform APIs.
PlatformTitleChange(browser, title);
}