Skip to content

Commit 0667622

Browse files
committed
Add picture-in-picture support for video (fixes issue #2776)
1 parent 1a661a2 commit 0667622

8 files changed

Lines changed: 95 additions & 11 deletions

File tree

BUILD.gn

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,12 @@ static_library("libcef_static") {
949949
deps += [ "//tools/v8_context_snapshot" ]
950950
}
951951

952+
if (toolkit_views) {
953+
deps += [
954+
"//ui/views",
955+
]
956+
}
957+
952958
if (use_aura) {
953959
sources += [
954960
"libcef/browser/native/window_delegate_view.cc",
@@ -1039,7 +1045,6 @@ static_library("libcef_static") {
10391045

10401046
if (toolkit_views) {
10411047
deps += [
1042-
"//ui/views",
10431048
"//ui/views/controls/webview",
10441049
]
10451050
}

libcef/browser/browser_host_impl.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "base/bind.h"
4343
#include "base/bind_helpers.h"
4444
#include "base/command_line.h"
45+
#include "chrome/browser/picture_in_picture/picture_in_picture_window_manager.h"
4546
#include "chrome/browser/printing/print_view_manager.h"
4647
#include "chrome/browser/spellchecker/spellcheck_factory.h"
4748
#include "chrome/browser/spellchecker/spellcheck_service.h"
@@ -1503,6 +1504,11 @@ bool CefBrowserHostImpl::IsPrintPreviewSupported() const {
15031504
return !IsWindowless();
15041505
}
15051506

1507+
bool CefBrowserHostImpl::IsPictureInPictureSupported() const {
1508+
// Not currently supported with OSR.
1509+
return !IsWindowless();
1510+
}
1511+
15061512
void CefBrowserHostImpl::WindowDestroyed() {
15071513
CEF_REQUIRE_UIT();
15081514
DCHECK(!window_destroyed_);
@@ -2501,6 +2507,23 @@ bool CefBrowserHostImpl::IsNeverVisible(content::WebContents* web_contents) {
25012507
return false;
25022508
}
25032509

2510+
content::PictureInPictureResult CefBrowserHostImpl::EnterPictureInPicture(
2511+
content::WebContents* web_contents,
2512+
const viz::SurfaceId& surface_id,
2513+
const gfx::Size& natural_size) {
2514+
if (!IsPictureInPictureSupported()) {
2515+
return content::PictureInPictureResult::kNotSupported;
2516+
}
2517+
2518+
return PictureInPictureWindowManager::GetInstance()->EnterPictureInPicture(
2519+
web_contents, surface_id, natural_size);
2520+
}
2521+
2522+
void CefBrowserHostImpl::ExitPictureInPicture() {
2523+
DCHECK(IsPictureInPictureSupported());
2524+
PictureInPictureWindowManager::GetInstance()->ExitPictureInPicture();
2525+
}
2526+
25042527
// content::WebContentsObserver methods.
25052528
// -----------------------------------------------------------------------------
25062529

libcef/browser/browser_host_impl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ class CefBrowserHostImpl : public CefBrowserHost,
277277
// Returns true if this browser supports print preview.
278278
bool IsPrintPreviewSupported() const;
279279

280+
// Returns true if this browser supports picture-in-picture.
281+
bool IsPictureInPictureSupported() const;
282+
280283
// Called when the OS window hosting the browser is destroyed.
281284
void WindowDestroyed();
282285

@@ -458,6 +461,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
458461
const GURL& security_origin,
459462
blink::mojom::MediaStreamType type) override;
460463
bool IsNeverVisible(content::WebContents* web_contents) override;
464+
content::PictureInPictureResult EnterPictureInPicture(
465+
content::WebContents* web_contents,
466+
const viz::SurfaceId& surface_id,
467+
const gfx::Size& natural_size) override;
468+
void ExitPictureInPicture() override;
461469

462470
// content::WebContentsObserver methods.
463471
using content::WebContentsObserver::BeforeUnloadFired;

libcef/browser/browser_main.cc

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
#if defined(USE_AURA)
4747
#include "ui/aura/env.h"
4848
#include "ui/display/screen.h"
49-
#include "ui/views/test/desktop_test_views_delegate.h"
5049
#include "ui/views/widget/desktop_aura/desktop_screen.h"
5150
#include "ui/wm/core/wm_state.h"
5251

@@ -55,6 +54,15 @@
5554
#endif
5655
#endif // defined(USE_AURA)
5756

57+
#if defined(TOOLKIT_VIEWS)
58+
#if defined(OS_MACOSX)
59+
#include "chrome/browser/ui/views/chrome_layout_provider.h"
60+
#include "chrome/browser/ui/views/chrome_views_delegate.h"
61+
#else
62+
#include "ui/views/test/desktop_test_views_delegate.h"
63+
#endif
64+
#endif // defined(TOOLKIT_VIEWS)
65+
5866
#if defined(USE_AURA) && defined(OS_LINUX)
5967
#include "ui/base/ime/init/input_method_initializer.h"
6068
#endif
@@ -91,15 +99,22 @@ void CefBrowserMainParts::ToolkitInitialized() {
9199
#if defined(USE_AURA)
92100
CHECK(aura::Env::GetInstance());
93101

94-
new views::DesktopTestViewsDelegate;
95-
96102
wm_state_.reset(new wm::WMState);
97103

98104
#if defined(OS_WIN)
99105
ui::CursorLoaderWin::SetCursorResourceModule(
100106
CefContentBrowserClient::Get()->GetResourceDllName());
101107
#endif
102108
#endif // defined(USE_AURA)
109+
110+
#if defined(TOOLKIT_VIEWS)
111+
#if defined(OS_MACOSX)
112+
views_delegate_ = std::make_unique<ChromeViewsDelegate>();
113+
layout_provider_ = ChromeLayoutProvider::CreateLayoutProvider();
114+
#else
115+
views_delegate_ = std::make_unique<views::DesktopTestViewsDelegate>();
116+
#endif
117+
#endif // defined(TOOLKIT_VIEWS)
103118
}
104119

105120
void CefBrowserMainParts::PreMainMessageLoopStart() {
@@ -207,8 +222,10 @@ void CefBrowserMainParts::PostDestroyThreads() {
207222
extensions_browser_client_.reset();
208223
}
209224

210-
#if defined(USE_AURA)
211-
// Delete the DesktopTestViewsDelegate.
212-
delete views::ViewsDelegate::GetInstance();
225+
#if defined(TOOLKIT_VIEWS)
226+
views_delegate_.reset();
227+
#if defined(OS_MACOSX)
228+
layout_provider_.reset();
213229
#endif
230+
#endif // defined(TOOLKIT_VIEWS)
214231
}

libcef/browser/browser_main.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ class WMState;
2929
}
3030
#endif
3131

32+
#if defined(TOOLKIT_VIEWS)
33+
namespace views {
34+
class ViewsDelegate;
35+
#if defined(OS_MACOSX)
36+
class LayoutProvider;
37+
#endif
38+
}
39+
#endif // defined(TOOLKIT_VIEWS)
40+
3241
class CefDevToolsDelegate;
3342

3443
class CefBrowserMainParts : public content::BrowserMainParts {
@@ -85,6 +94,13 @@ class CefBrowserMainParts : public content::BrowserMainParts {
8594
std::unique_ptr<wm::WMState> wm_state_;
8695
#endif
8796

97+
#if defined(TOOLKIT_VIEWS)
98+
std::unique_ptr<views::ViewsDelegate> views_delegate_;
99+
#if defined(OS_MACOSX)
100+
std::unique_ptr<views::LayoutProvider> layout_provider_;
101+
#endif
102+
#endif // defined(TOOLKIT_VIEWS)
103+
88104
DISALLOW_COPY_AND_ASSIGN(CefBrowserMainParts);
89105
};
90106

libcef/browser/content_browser_client.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,18 @@ bool CefContentBrowserClient::HandleExternalProtocol(
13621362
return true;
13631363
}
13641364

1365+
std::unique_ptr<content::OverlayWindow>
1366+
CefContentBrowserClient::CreateWindowForPictureInPicture(
1367+
content::PictureInPictureWindowController* controller) {
1368+
// Note: content::OverlayWindow::Create() is defined by platform-specific
1369+
// implementation in chrome/browser/ui/views. This layering hack, which goes
1370+
// through //content and ContentBrowserClient, allows us to work around the
1371+
// dependency constraints that disallow directly calling
1372+
// chrome/browser/ui/views code either from here or from other code in
1373+
// chrome/browser.
1374+
return content::OverlayWindow::Create(controller);
1375+
}
1376+
13651377
std::string CefContentBrowserClient::GetProduct() {
13661378
// Match the logic in chrome_content_browser_client.cc GetProduct().
13671379
return ::GetProduct();

libcef/browser/content_browser_client.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ class CefContentBrowserClient : public content::ContentBrowserClient {
193193
const network::ResourceRequest& request,
194194
network::mojom::URLLoaderFactoryRequest* factory_request,
195195
network::mojom::URLLoaderFactoryPtr* out_factory) override;
196+
std::unique_ptr<content::OverlayWindow> CreateWindowForPictureInPicture(
197+
content::PictureInPictureWindowController* controller) override;
196198

197199
std::string GetProduct() override;
198200
std::string GetChromeProduct() override;

libcef/browser/prefs/renderer_prefs.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,13 @@ void PopulateWebPreferences(content::RenderViewHost* rvh,
342342
// Set preferences based on the extension.
343343
SetExtensionPrefs(rvh, web);
344344

345-
// Set preferences based on CefBrowserSettings.
346-
if (browser)
345+
if (browser) {
346+
// Set preferences based on CefBrowserSettings.
347347
SetCefPrefs(browser->settings(), web);
348348

349-
// Set the background color for the WebView.
350-
if (browser) {
349+
web.picture_in_picture_enabled = browser->IsPictureInPictureSupported();
350+
351+
// Set the background color for the WebView.
351352
web.base_background_color = browser->GetBackgroundColor();
352353
} else {
353354
// We don't know for sure that the browser will be windowless but assume

0 commit comments

Comments
 (0)