diff --git a/BUILD.gn b/BUILD.gn index 863088054..6aa0a84dc 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -949,6 +949,12 @@ static_library("libcef_static") { deps += [ "//tools/v8_context_snapshot" ] } + if (toolkit_views) { + deps += [ + "//ui/views", + ] + } + if (use_aura) { sources += [ "libcef/browser/native/window_delegate_view.cc", @@ -1039,7 +1045,6 @@ static_library("libcef_static") { if (toolkit_views) { deps += [ - "//ui/views", "//ui/views/controls/webview", ] } diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 3a192f177..9d6ebc948 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -42,6 +42,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h" #include "chrome/browser/printing/print_view_manager.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_service.h" @@ -1503,6 +1504,11 @@ bool CefBrowserHostImpl::IsPrintPreviewSupported() const { return !IsWindowless(); } +bool CefBrowserHostImpl::IsPictureInPictureSupported() const { + // Not currently supported with OSR. + return !IsWindowless(); +} + void CefBrowserHostImpl::WindowDestroyed() { CEF_REQUIRE_UIT(); DCHECK(!window_destroyed_); @@ -2501,6 +2507,23 @@ bool CefBrowserHostImpl::IsNeverVisible(content::WebContents* web_contents) { return false; } +content::PictureInPictureResult CefBrowserHostImpl::EnterPictureInPicture( + content::WebContents* web_contents, + const viz::SurfaceId& surface_id, + const gfx::Size& natural_size) { + if (!IsPictureInPictureSupported()) { + return content::PictureInPictureResult::kNotSupported; + } + + return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture( + web_contents, surface_id, natural_size); +} + +void CefBrowserHostImpl::ExitPictureInPicture() { + DCHECK(IsPictureInPictureSupported()); + PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture(); +} + // content::WebContentsObserver methods. // ----------------------------------------------------------------------------- diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index be9ce3021..d4cdffc99 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -277,6 +277,9 @@ class CefBrowserHostImpl : public CefBrowserHost, // Returns true if this browser supports print preview. bool IsPrintPreviewSupported() 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(); @@ -458,6 +461,11 @@ class CefBrowserHostImpl : public CefBrowserHost, const GURL& security_origin, blink::mojom::MediaStreamType type) override; bool IsNeverVisible(content::WebContents* web_contents) override; + content::PictureInPictureResult EnterPictureInPicture( + content::WebContents* web_contents, + const viz::SurfaceId& surface_id, + const gfx::Size& natural_size) override; + void ExitPictureInPicture() override; // content::WebContentsObserver methods. using content::WebContentsObserver::BeforeUnloadFired; diff --git a/libcef/browser/browser_main.cc b/libcef/browser/browser_main.cc index 9447da957..de182f9e4 100644 --- a/libcef/browser/browser_main.cc +++ b/libcef/browser/browser_main.cc @@ -46,7 +46,6 @@ #if defined(USE_AURA) #include "ui/aura/env.h" #include "ui/display/screen.h" -#include "ui/views/test/desktop_test_views_delegate.h" #include "ui/views/widget/desktop_aura/desktop_screen.h" #include "ui/wm/core/wm_state.h" @@ -55,6 +54,15 @@ #endif #endif // defined(USE_AURA) +#if defined(TOOLKIT_VIEWS) +#if defined(OS_MACOSX) +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/chrome_views_delegate.h" +#else +#include "ui/views/test/desktop_test_views_delegate.h" +#endif +#endif // defined(TOOLKIT_VIEWS) + #if defined(USE_AURA) && defined(OS_LINUX) #include "ui/base/ime/init/input_method_initializer.h" #endif @@ -91,8 +99,6 @@ void CefBrowserMainParts::ToolkitInitialized() { #if defined(USE_AURA) CHECK(aura::Env::GetInstance()); - new views::DesktopTestViewsDelegate; - wm_state_.reset(new wm::WMState); #if defined(OS_WIN) @@ -100,6 +106,15 @@ void CefBrowserMainParts::ToolkitInitialized() { CefContentBrowserClient::Get()->GetResourceDllName()); #endif #endif // defined(USE_AURA) + +#if defined(TOOLKIT_VIEWS) +#if defined(OS_MACOSX) + views_delegate_ = std::make_unique(); + layout_provider_ = ChromeLayoutProvider::CreateLayoutProvider(); +#else + views_delegate_ = std::make_unique(); +#endif +#endif // defined(TOOLKIT_VIEWS) } void CefBrowserMainParts::PreMainMessageLoopStart() { @@ -207,8 +222,10 @@ void CefBrowserMainParts::PostDestroyThreads() { extensions_browser_client_.reset(); } -#if defined(USE_AURA) - // Delete the DesktopTestViewsDelegate. - delete views::ViewsDelegate::GetInstance(); +#if defined(TOOLKIT_VIEWS) + views_delegate_.reset(); +#if defined(OS_MACOSX) + layout_provider_.reset(); #endif +#endif // defined(TOOLKIT_VIEWS) } diff --git a/libcef/browser/browser_main.h b/libcef/browser/browser_main.h index 4b9363438..582769787 100644 --- a/libcef/browser/browser_main.h +++ b/libcef/browser/browser_main.h @@ -29,6 +29,15 @@ class WMState; } #endif +#if defined(TOOLKIT_VIEWS) +namespace views { +class ViewsDelegate; +#if defined(OS_MACOSX) +class LayoutProvider; +#endif +} +#endif // defined(TOOLKIT_VIEWS) + class CefDevToolsDelegate; class CefBrowserMainParts : public content::BrowserMainParts { @@ -85,6 +94,13 @@ class CefBrowserMainParts : public content::BrowserMainParts { std::unique_ptr wm_state_; #endif +#if defined(TOOLKIT_VIEWS) + std::unique_ptr views_delegate_; +#if defined(OS_MACOSX) + std::unique_ptr layout_provider_; +#endif +#endif // defined(TOOLKIT_VIEWS) + DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts); }; diff --git a/libcef/browser/content_browser_client.cc b/libcef/browser/content_browser_client.cc index 7563a391f..2ee088960 100644 --- a/libcef/browser/content_browser_client.cc +++ b/libcef/browser/content_browser_client.cc @@ -1362,6 +1362,18 @@ bool CefContentBrowserClient::HandleExternalProtocol( return true; } +std::unique_ptr +CefContentBrowserClient::CreateWindowForPictureInPicture( + content::PictureInPictureWindowController* controller) { + // Note: content::OverlayWindow::Create() is defined by platform-specific + // implementation in chrome/browser/ui/views. This layering hack, which goes + // through //content and ContentBrowserClient, allows us to work around the + // dependency constraints that disallow directly calling + // chrome/browser/ui/views code either from here or from other code in + // chrome/browser. + return content::OverlayWindow::Create(controller); +} + std::string CefContentBrowserClient::GetProduct() { // Match the logic in chrome_content_browser_client.cc GetProduct(). return ::GetProduct(); diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index 01e7c46d4..0354def87 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -193,6 +193,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient { const network::ResourceRequest& request, network::mojom::URLLoaderFactoryRequest* factory_request, network::mojom::URLLoaderFactoryPtr* out_factory) override; + std::unique_ptr CreateWindowForPictureInPicture( + content::PictureInPictureWindowController* controller) override; std::string GetProduct() override; std::string GetChromeProduct() override; diff --git a/libcef/browser/prefs/renderer_prefs.cc b/libcef/browser/prefs/renderer_prefs.cc index f94e068e2..2fbb7d0e8 100644 --- a/libcef/browser/prefs/renderer_prefs.cc +++ b/libcef/browser/prefs/renderer_prefs.cc @@ -342,12 +342,13 @@ void PopulateWebPreferences(content::RenderViewHost* rvh, // Set preferences based on the extension. SetExtensionPrefs(rvh, web); - // Set preferences based on CefBrowserSettings. - if (browser) + if (browser) { + // Set preferences based on CefBrowserSettings. SetCefPrefs(browser->settings(), web); - // Set the background color for the WebView. - if (browser) { + web.picture_in_picture_enabled = browser->IsPictureInPictureSupported(); + + // Set the background color for the WebView. web.base_background_color = browser->GetBackgroundColor(); } else { // We don't know for sure that the browser will be windowless but assume