Support full-screen Flash with off-screen rendering (issue #1648)

This commit is contained in:
Marshall Greenblatt 2015-06-11 11:00:05 -04:00
parent 378a64b39a
commit de05577c86
5 changed files with 101 additions and 70 deletions

View File

@ -312,6 +312,20 @@ class UploadFolderHelper :
DISALLOW_COPY_AND_ASSIGN(UploadFolderHelper);
};
CefRenderWidgetHostViewOSR* GetOSRHostView(content::WebContents* web_contents) {
CefRenderWidgetHostViewOSR* fs_view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents->GetFullscreenRenderWidgetHostView());
if (fs_view)
return fs_view;
content::RenderViewHost* host = web_contents->GetRenderViewHost();
if (host)
return static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
return NULL;
}
} // namespace
@ -1020,15 +1034,12 @@ void CefBrowserHostImpl::WasResized() {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
if (!IsWindowless()) {
host->WasResized();
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->WasResized();
} else {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->WasResized();
}
@ -1049,12 +1060,7 @@ void CefBrowserHostImpl::WasHidden(bool hidden) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view) {
if (hidden)
view->Hide();
@ -1078,12 +1084,7 @@ void CefBrowserHostImpl::NotifyScreenInfoChanged() {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->OnScreenInfoChanged();
}
@ -1103,12 +1104,7 @@ void CefBrowserHostImpl::Invalidate(PaintElementType type) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->Invalidate(type);
}
@ -1123,18 +1119,15 @@ void CefBrowserHostImpl::SendKeyEvent(const CefKeyEvent& event) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
content::NativeWebKeyboardEvent web_event;
PlatformTranslateKeyEvent(web_event, event);
if (!IsWindowless()) {
host->ForwardKeyboardEvent(web_event);
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardKeyboardEvent(web_event);
} else {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->SendKeyEvent(web_event);
}
@ -1182,18 +1175,15 @@ void CefBrowserHostImpl::SendMouseWheelEvent(const CefMouseEvent& event,
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
blink::WebMouseWheelEvent web_event;
PlatformTranslateWheelEvent(web_event, event, deltaX, deltaY);
if (!IsWindowless()) {
host->ForwardWheelEvent(web_event);
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardWheelEvent(web_event);
} else {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->SendMouseWheelEvent(web_event);
}
@ -1233,15 +1223,12 @@ void CefBrowserHostImpl::SendMouseEvent(const blink::WebMouseEvent& event) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
if (!IsWindowless()) {
host->ForwardMouseEvent(event);
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (host)
host->ForwardMouseEvent(event);
} else {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->SendMouseEvent(event);
}
@ -1260,12 +1247,7 @@ void CefBrowserHostImpl::SendFocusEvent(bool setFocus) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->SendFocusEvent(setFocus);
}
@ -1332,12 +1314,7 @@ void CefBrowserHostImpl::SetWindowlessFrameRate(int frame_rate) {
if (!web_contents())
return;
content::RenderViewHost* host = web_contents()->GetRenderViewHost();
if (!host)
return;
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(host->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents());
if (view)
view->UpdateFrameRate();
}
@ -1891,6 +1868,12 @@ void CefBrowserHostImpl::RunFileChooser(
callback));
}
bool CefBrowserHostImpl::EmbedsFullscreenWidget() const {
// When using windowless rendering do not allow Flash to create its own full-
// screen widget.
return IsWindowless();
}
void CefBrowserHostImpl::EnterFullscreenModeForTab(
content::WebContents* web_contents,
const GURL& origin) {
@ -2954,9 +2937,7 @@ CefBrowserHostImpl::CefBrowserHostImpl(
RenderViewCreated(web_contents->GetRenderViewHost());
if (IsWindowless()) {
CefRenderWidgetHostViewOSR* view =
static_cast<CefRenderWidgetHostViewOSR*>(
web_contents->GetRenderViewHost()->GetView());
CefRenderWidgetHostViewOSR* view = GetOSRHostView(web_contents);
if (view)
view->set_browser_impl(this);
}

View File

@ -405,6 +405,7 @@ class CefBrowserHostImpl : public CefBrowserHost,
void RunFileChooser(
content::WebContents* web_contents,
const content::FileChooserParams& params) override;
bool EmbedsFullscreenWidget() const override;
void EnterFullscreenModeForTab(content::WebContents* web_contents,
const GURL& origin) override;
void ExitFullscreenModeForTab(content::WebContents* web_contents) override;

View File

@ -436,7 +436,8 @@ class CefBeginFrameTimer : public cc::TimeSourceClient {
CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
content::RenderWidgetHost* widget)
content::RenderWidgetHost* widget,
CefRenderWidgetHostViewOSR* parent_host_view)
: scale_factor_(kDefaultScaleFactor),
frame_rate_threshold_ms_(0),
delegated_frame_host_(new content::DelegatedFrameHost(this)),
@ -445,8 +446,10 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR(
hold_resize_(false),
pending_resize_(false),
render_widget_host_(content::RenderWidgetHostImpl::From(widget)),
parent_host_view_(NULL),
has_parent_(parent_host_view != NULL),
parent_host_view_(parent_host_view),
popup_host_view_(NULL),
child_host_view_(NULL),
is_showing_(true),
is_destroyed_(false),
is_scroll_offset_changed_pending_(false),
@ -497,7 +500,21 @@ CefRenderWidgetHostViewOSR::~CefRenderWidgetHostViewOSR() {
root_layer_.reset(NULL);
}
// Called for full-screen widgets.
void CefRenderWidgetHostViewOSR::InitAsChild(gfx::NativeView parent_view) {
DCHECK(parent_host_view_);
browser_impl_ = parent_host_view_->browser_impl();
DCHECK(browser_impl_.get());
if (parent_host_view_->child_host_view_) {
// Cancel the previous popup widget.
parent_host_view_->child_host_view_->CancelChildWidget();
}
parent_host_view_->set_child_host_view(this);
ResizeRootLayer();
Show();
}
content::RenderWidgetHost*
@ -675,8 +692,7 @@ void CefRenderWidgetHostViewOSR::OnSwapCompositorFrame(
void CefRenderWidgetHostViewOSR::InitAsPopup(
content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos) {
parent_host_view_ = static_cast<CefRenderWidgetHostViewOSR*>(
parent_host_view);
DCHECK_EQ(parent_host_view_, parent_host_view);
browser_impl_ = parent_host_view_->browser_impl();
DCHECK(browser_impl_.get());
@ -785,17 +801,23 @@ void CefRenderWidgetHostViewOSR::RenderProcessGone(
render_widget_host_ = NULL;
parent_host_view_ = NULL;
popup_host_view_ = NULL;
child_host_view_ = NULL;
}
void CefRenderWidgetHostViewOSR::Destroy() {
if (!is_destroyed_) {
is_destroyed_ = true;
if (IsPopupWidget()) {
CancelPopupWidget();
if (has_parent_) {
if (IsPopupWidget())
CancelPopupWidget();
else
CancelChildWidget();
} else {
if (popup_host_view_)
popup_host_view_->CancelPopupWidget();
if (child_host_view_)
child_host_view_->CancelChildWidget();
Hide();
}
}
@ -1393,6 +1415,24 @@ void CefRenderWidgetHostViewOSR::CancelPopupWidget() {
}
}
void CefRenderWidgetHostViewOSR::CancelChildWidget() {
if (render_widget_host_)
render_widget_host_->LostCapture();
Hide();
if (parent_host_view_) {
parent_host_view_->set_child_host_view(NULL);
parent_host_view_ = NULL;
}
if (render_widget_host_ && !is_destroyed_) {
is_destroyed_ = true;
// Results in a call to Destroy().
render_widget_host_->Shutdown();
}
}
void CefRenderWidgetHostViewOSR::OnScrollOffsetChanged() {
if (browser_impl_.get()) {
CefRefPtr<CefRenderHandler> handler =

View File

@ -78,7 +78,8 @@ class CefRenderWidgetHostViewOSR
public ui::CompositorDelegate,
public content::DelegatedFrameHostClient {
public:
explicit CefRenderWidgetHostViewOSR(content::RenderWidgetHost* widget);
CefRenderWidgetHostViewOSR(content::RenderWidgetHost* widget,
CefRenderWidgetHostViewOSR* parent_host_view);
~CefRenderWidgetHostViewOSR() override;
// RenderWidgetHostView implementation.
@ -264,6 +265,9 @@ class CefRenderWidgetHostViewOSR
void set_popup_host_view(CefRenderWidgetHostViewOSR* popup_view) {
popup_host_view_ = popup_view;
}
void set_child_host_view(CefRenderWidgetHostViewOSR* popup_view) {
child_host_view_ = popup_view;
}
ui::Compositor* compositor() const { return compositor_.get(); }
content::RenderWidgetHostImpl* render_widget_host() const
@ -285,6 +289,7 @@ class CefRenderWidgetHostViewOSR
base::TimeDelta vsync_period);
void CancelPopupWidget();
void CancelChildWidget();
void OnScrollOffsetChanged();
@ -349,8 +354,11 @@ class CefRenderWidgetHostViewOSR
// |render_widget_host_| is NULL and the message loop is run one last time
// Message handlers must check for a NULL |render_widget_host_|.
content::RenderWidgetHostImpl* render_widget_host_;
bool has_parent_;
CefRenderWidgetHostViewOSR* parent_host_view_;
CefRenderWidgetHostViewOSR* popup_host_view_;
CefRenderWidgetHostViewOSR* child_host_view_;
CefRefPtr<CefBrowserHostImpl> browser_impl_;

View File

@ -75,14 +75,15 @@ content::RenderWidgetHostViewBase* CefWebContentsViewOSR::CreateViewForWidget(
render_widget_host->GetView());
}
view_ = new CefRenderWidgetHostViewOSR(render_widget_host);
view_ = new CefRenderWidgetHostViewOSR(render_widget_host, NULL);
return view_;
}
// Called for popup and fullscreen widgets.
content::RenderWidgetHostViewBase*
CefWebContentsViewOSR::CreateViewForPopupWidget(
content::RenderWidgetHost* render_widget_host) {
return new CefRenderWidgetHostViewOSR(render_widget_host);
return new CefRenderWidgetHostViewOSR(render_widget_host, view_);
}
void CefWebContentsViewOSR::SetPageTitle(const base::string16& title) {