summaryrefslogtreecommitdiff
path: root/chromium/ui/views/controls/webview/webview.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/controls/webview/webview.cc')
-rw-r--r--chromium/ui/views/controls/webview/webview.cc176
1 files changed, 104 insertions, 72 deletions
diff --git a/chromium/ui/views/controls/webview/webview.cc b/chromium/ui/views/controls/webview/webview.cc
index 89ac03758e5..9169ac0ecbf 100644
--- a/chromium/ui/views/controls/webview/webview.cc
+++ b/chromium/ui/views/controls/webview/webview.cc
@@ -4,6 +4,7 @@
#include "ui/views/controls/webview/webview.h"
+#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_details.h"
@@ -17,7 +18,7 @@
#include "ipc/ipc_message.h"
#include "ui/base/accessibility/accessibility_types.h"
#include "ui/base/accessibility/accessible_view_state.h"
-#include "ui/base/events/event.h"
+#include "ui/events/event.h"
#include "ui/views/accessibility/native_view_accessibility.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/focus/focus_manager.h"
@@ -34,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_);
@@ -63,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,
@@ -125,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) {
@@ -162,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();
}
@@ -185,26 +218,22 @@ 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, AccessibleWebView implementation:
+// WebView, content::WebContentsObserver implementation:
-gfx::NativeViewAccessible WebView::AccessibleObjectFromChildId(long child_id) {
-#if defined(OS_WIN) && defined(USE_AURA)
- if (!web_contents_)
- return NULL;
- content::RenderWidgetHostView* host_view =
- web_contents_->GetRenderWidgetHostView();
- if (host_view)
- return host_view->AccessibleObjectFromChildId(child_id);
- return NULL;
-#else
- NOTIMPLEMENTED();
- return NULL;
-#endif
+void WebView::DidShowFullscreenWidget(int routing_id) {
+ DCHECK(embed_fullscreen_widget_mode_enabled_);
+ ReattachForFullscreenChange(true);
}
-View* WebView::AsView() {
- return this;
+void WebView::DidDestroyFullscreenWidget(int routing_id) {
+ DCHECK(embed_fullscreen_widget_mode_enabled_);
+ ReattachForFullscreenChange(false);
}
////////////////////////////////////////////////////////////////////////////////
@@ -213,66 +242,69 @@ View* WebView::AsView() {
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(