| Index: ui/views/controls/webview/webview.cc
|
| diff --git a/ui/views/controls/webview/webview.cc b/ui/views/controls/webview/webview.cc
|
| index 28b8b7adc21dff5546bf12d485e6e1b559b73f1d..15fed841ba1259a5347daef33cbe5027892e7348 100644
|
| --- a/ui/views/controls/webview/webview.cc
|
| +++ b/ui/views/controls/webview/webview.cc
|
| @@ -35,6 +35,8 @@ const char WebView::kViewClassName[] = "WebView";
|
| WebView::WebView(content::BrowserContext* browser_context)
|
| : wcv_holder_(new NativeViewHost),
|
| web_contents_(NULL),
|
| + embed_fullscreen_widget_mode_enabled_(false),
|
| + is_embedding_fullscreen_widget_(false),
|
| browser_context_(browser_context),
|
| allow_accelerators_(false) {
|
| AddChildView(wcv_holder_);
|
| @@ -64,11 +66,35 @@ void WebView::SetWebContents(content::WebContents* web_contents) {
|
| if (web_contents == web_contents_)
|
| return;
|
| DetachWebContents();
|
| - wc_owner_.reset();
|
| + if (wc_owner_ != web_contents)
|
| + wc_owner_.reset();
|
| web_contents_ = web_contents;
|
| + if (embed_fullscreen_widget_mode_enabled_) {
|
| + WebContentsObserver::Observe(web_contents_);
|
| + is_embedding_fullscreen_widget_ =
|
| + web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
|
| + } else {
|
| + is_embedding_fullscreen_widget_ = false;
|
| + }
|
| AttachWebContents();
|
| }
|
|
|
| +void WebView::SetEmbedFullscreenWidgetMode(bool enable) {
|
| + bool should_be_embedded = enable;
|
| + if (!embed_fullscreen_widget_mode_enabled_ && enable) {
|
| + DCHECK(!is_embedding_fullscreen_widget_);
|
| + embed_fullscreen_widget_mode_enabled_ = true;
|
| + WebContentsObserver::Observe(web_contents_);
|
| + should_be_embedded =
|
| + web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
|
| + } else if (embed_fullscreen_widget_mode_enabled_ && !enable) {
|
| + embed_fullscreen_widget_mode_enabled_ = false;
|
| + WebContentsObserver::Observe(NULL);
|
| + }
|
| + if (should_be_embedded != is_embedding_fullscreen_widget_)
|
| + ReattachForFullscreenChange(should_be_embedded);
|
| +}
|
| +
|
| void WebView::LoadInitialURL(const GURL& url) {
|
| GetWebContents()->GetController().LoadURL(
|
| url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL,
|
| @@ -126,8 +152,16 @@ bool WebView::IsFocusable() const {
|
| }
|
|
|
| void WebView::OnFocus() {
|
| - if (web_contents_)
|
| + if (!web_contents_)
|
| + return;
|
| + if (is_embedding_fullscreen_widget_) {
|
| + content::RenderWidgetHostView* const current_fs_view =
|
| + web_contents_->GetFullscreenRenderWidgetHostView();
|
| + if (current_fs_view)
|
| + current_fs_view->Focus();
|
| + } else {
|
| web_contents_->GetView()->Focus();
|
| + }
|
| }
|
|
|
| void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
|
| @@ -163,15 +197,13 @@ void WebView::Observe(int type,
|
| const content::NotificationSource& source,
|
| const content::NotificationDetails& details) {
|
| if (type == content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED) {
|
| - std::pair<content::RenderViewHost*, content::RenderViewHost*>*
|
| - switched_details =
|
| - content::Details<std::pair<content::RenderViewHost*,
|
| - content::RenderViewHost*> >(
|
| - details).ptr();
|
| - RenderViewHostChanged(switched_details->first,
|
| - switched_details->second);
|
| + FocusManager* const focus_manager = GetFocusManager();
|
| + if (focus_manager && focus_manager->GetFocusedView() == this)
|
| + OnFocus();
|
| } else if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) {
|
| - WebContentsDestroyed(content::Source<content::WebContents>(source).ptr());
|
| + DCHECK(content::Source<content::WebContents>(source).ptr() ==
|
| + web_contents_);
|
| + SetWebContents(NULL);
|
| } else {
|
| NOTREACHED();
|
| }
|
| @@ -186,72 +218,93 @@ void WebView::WebContentsFocused(content::WebContents* web_contents) {
|
| OnWebContentsFocused(web_contents_);
|
| }
|
|
|
| +bool WebView::EmbedsFullscreenWidget() const {
|
| + DCHECK(wc_owner_.get());
|
| + return embed_fullscreen_widget_mode_enabled_;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// WebView, content::WebContentsObserver implementation:
|
| +
|
| +void WebView::DidShowFullscreenWidget(int routing_id) {
|
| + DCHECK(embed_fullscreen_widget_mode_enabled_);
|
| + ReattachForFullscreenChange(true);
|
| +}
|
| +
|
| +void WebView::DidDestroyFullscreenWidget(int routing_id) {
|
| + DCHECK(embed_fullscreen_widget_mode_enabled_);
|
| + ReattachForFullscreenChange(false);
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // WebView, private:
|
|
|
| void WebView::AttachWebContents() {
|
| // Prevents attachment if the WebView isn't already in a Widget, or it's
|
| // already attached.
|
| - if (!GetWidget() || !web_contents_ ||
|
| - wcv_holder_->native_view() == web_contents_->GetView()->GetNativeView()) {
|
| + if (!GetWidget() || !web_contents_)
|
| return;
|
| - }
|
|
|
| - if (web_contents_) {
|
| - wcv_holder_->Attach(web_contents_->GetView()->GetNativeView());
|
| -
|
| - // The WebContentsView will not be focused automatically when it is
|
| - // attached, so we need to pass on focus to it if the FocusManager thinks
|
| - // the WebView is focused. Note that not every Widget has a focus manager.
|
| - FocusManager* focus_manager = GetFocusManager();
|
| - if (focus_manager && focus_manager->GetFocusedView() == this)
|
| - web_contents_->GetView()->Focus();
|
| -
|
| - registrar_.Add(
|
| - this,
|
| - content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
|
| - content::Source<content::NavigationController>(
|
| - &web_contents_->GetController()));
|
| - registrar_.Add(
|
| - this,
|
| - content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| - content::Source<content::WebContents>(web_contents_));
|
| - }
|
| + const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ?
|
| + web_contents_->GetFullscreenRenderWidgetHostView()->GetNativeView() :
|
| + web_contents_->GetView()->GetNativeView();
|
| + if (wcv_holder_->native_view() == view_to_attach)
|
| + return;
|
| + wcv_holder_->Attach(view_to_attach);
|
| +
|
| + // The view will not be focused automatically when it is attached, so we need
|
| + // to pass on focus to it if the FocusManager thinks the view is focused. Note
|
| + // that not every Widget has a focus manager.
|
| + FocusManager* const focus_manager = GetFocusManager();
|
| + if (focus_manager && focus_manager->GetFocusedView() == this)
|
| + OnFocus();
|
| +
|
| + registrar_.Add(
|
| + this,
|
| + content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
|
| + content::Source<content::NavigationController>(
|
| + &web_contents_->GetController()));
|
| + registrar_.Add(
|
| + this,
|
| + content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
|
| + content::Source<content::WebContents>(web_contents_));
|
|
|
| #if defined(OS_WIN) && defined(USE_AURA)
|
| - web_contents_->SetParentNativeViewAccessible(
|
| - parent()->GetNativeViewAccessible());
|
| + if (!is_embedding_fullscreen_widget_) {
|
| + web_contents_->SetParentNativeViewAccessible(
|
| + parent()->GetNativeViewAccessible());
|
| + }
|
| #endif
|
| }
|
|
|
| void WebView::DetachWebContents() {
|
| if (web_contents_) {
|
| wcv_holder_->Detach();
|
| -#if defined(OS_WIN) && !defined(USE_AURA)
|
| - // TODO(beng): This should either not be necessary, or be done implicitly by
|
| - // NativeViewHostWin on Detach(). As it stands, this is needed so that the
|
| - // view of the detached contents knows to tell the renderer it's been
|
| - // hidden.
|
| - //
|
| - // Moving this out of here would also mean we wouldn't be potentially
|
| - // calling member functions on a half-destroyed WebContents.
|
| - ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE);
|
| -#elif defined(OS_WIN) && defined(USE_AURA)
|
| - web_contents_->SetParentNativeViewAccessible(NULL);
|
| +#if defined(OS_WIN)
|
| + if (!is_embedding_fullscreen_widget_) {
|
| +#if !defined(USE_AURA)
|
| + // TODO(beng): This should either not be necessary, or be done implicitly
|
| + // by NativeViewHostWin on Detach(). As it stands, this is needed so that
|
| + // the of the detached contents knows to tell the renderer it's been
|
| + // hidden.
|
| + //
|
| + // Moving this out of here would also mean we wouldn't be potentially
|
| + // calling member functions on a half-destroyed WebContents.
|
| + ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE);
|
| +#else
|
| + web_contents_->SetParentNativeViewAccessible(NULL);
|
| +#endif
|
| + }
|
| #endif
|
| }
|
| registrar_.RemoveAll();
|
| }
|
|
|
| -void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
|
| - content::RenderViewHost* new_host) {
|
| - if (GetFocusManager()->GetFocusedView() == this)
|
| - web_contents_->GetView()->Focus();
|
| -}
|
| -
|
| -void WebView::WebContentsDestroyed(content::WebContents* web_contents) {
|
| - DCHECK(web_contents == web_contents_);
|
| - SetWebContents(NULL);
|
| +void WebView::ReattachForFullscreenChange(bool enter_fullscreen) {
|
| + DetachWebContents();
|
| + is_embedding_fullscreen_widget_ = enter_fullscreen &&
|
| + web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
|
| + AttachWebContents();
|
| }
|
|
|
| content::WebContents* WebView::CreateWebContents(
|
|
|