Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: ui/views/controls/webview/webview.cc

Issue 23477051: Embed Flash Fullscreen widget within browser window. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/controls/webview/webview.h" 5 #include "ui/views/controls/webview/webview.h"
6 6
7 #include "content/public/browser/browser_accessibility_state.h" 7 #include "content/public/browser/browser_accessibility_state.h"
8 #include "content/public/browser/browser_context.h" 8 #include "content/public/browser/browser_context.h"
9 #include "content/public/browser/navigation_controller.h" 9 #include "content/public/browser/navigation_controller.h"
10 #include "content/public/browser/notification_details.h" 10 #include "content/public/browser/notification_details.h"
11 #include "content/public/browser/notification_registrar.h" 11 #include "content/public/browser/notification_registrar.h"
12 #include "content/public/browser/notification_source.h" 12 #include "content/public/browser/notification_source.h"
13 #include "content/public/browser/notification_types.h" 13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_view_host.h" 14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/render_widget_host_view.h" 15 #include "content/public/browser/render_widget_host_view.h"
16 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_observer.h"
17 #include "content/public/browser/web_contents_view.h" 18 #include "content/public/browser/web_contents_view.h"
18 #include "ipc/ipc_message.h" 19 #include "ipc/ipc_message.h"
19 #include "ui/base/accessibility/accessibility_types.h" 20 #include "ui/base/accessibility/accessibility_types.h"
20 #include "ui/base/accessibility/accessible_view_state.h" 21 #include "ui/base/accessibility/accessible_view_state.h"
21 #include "ui/base/events/event.h" 22 #include "ui/base/events/event.h"
22 #include "ui/views/accessibility/native_view_accessibility.h" 23 #include "ui/views/accessibility/native_view_accessibility.h"
23 #include "ui/views/controls/native/native_view_host.h" 24 #include "ui/views/controls/native/native_view_host.h"
24 #include "ui/views/focus/focus_manager.h" 25 #include "ui/views/focus/focus_manager.h"
25 #include "ui/views/views_delegate.h" 26 #include "ui/views/views_delegate.h"
26 27
27 namespace views { 28 namespace views {
28 29
29 // static 30 // static
30 const char WebView::kViewClassName[] = "WebView"; 31 const char WebView::kViewClassName[] = "WebView";
31 32
33 class WebView::FullscreenObserver : public content::WebContentsObserver {
sky 2013/09/10 19:38:58 Add a description. Is there a particular reason y
miu 2013/09/11 03:57:03 Done, and also for its "cousin" in the Mac cocoa U
34 public:
35 explicit FullscreenObserver(WebView* view) : view_(view) {}
36
37 void Observe(content::WebContents* new_web_contents) {
38 WebContentsObserver::Observe(new_web_contents);
39 }
40
41 virtual void DidShowFullscreenWidget(int routing_id) OVERRIDE {
42 view_->ReattachForFullscreenChange(true);
43 }
44
45 virtual void DidDestroyFullscreenWidget(int routing_id) OVERRIDE {
46 view_->ReattachForFullscreenChange(false);
47 }
48
49 private:
50 WebView* const view_;
sky 2013/09/10 19:38:58 members at the end of a section.
miu 2013/09/11 03:57:03 Done.
51
52 // Workaround for MSVC++ linker bug/feature that requires
53 // instantiation of the inline IPC::Listener methods in all translation units.
54 virtual void OnChannelConnected(int32 peer_id) OVERRIDE {}
55 virtual void OnChannelError() OVERRIDE {}
56 };
sky 2013/09/10 19:38:58 DISALLOW...
miu 2013/09/11 03:57:03 Done.
57
32 //////////////////////////////////////////////////////////////////////////////// 58 ////////////////////////////////////////////////////////////////////////////////
33 // WebView, public: 59 // WebView, public:
34 60
35 WebView::WebView(content::BrowserContext* browser_context) 61 WebView::WebView(content::BrowserContext* browser_context)
36 : wcv_holder_(new NativeViewHost), 62 : wcv_holder_(new NativeViewHost),
37 web_contents_(NULL), 63 web_contents_(NULL),
64 is_embedding_fullscreen_widget_(false),
38 browser_context_(browser_context), 65 browser_context_(browser_context),
39 allow_accelerators_(false) { 66 allow_accelerators_(false) {
40 AddChildView(wcv_holder_); 67 AddChildView(wcv_holder_);
41 NativeViewAccessibility::RegisterWebView(this); 68 NativeViewAccessibility::RegisterWebView(this);
42 } 69 }
43 70
44 WebView::~WebView() { 71 WebView::~WebView() {
45 NativeViewAccessibility::UnregisterWebView(this); 72 NativeViewAccessibility::UnregisterWebView(this);
46 } 73 }
47 74
48 content::WebContents* WebView::GetWebContents() { 75 content::WebContents* WebView::GetWebContents() {
49 CreateWebContentsWithSiteInstance(NULL); 76 CreateWebContentsWithSiteInstance(NULL);
50 return web_contents_; 77 return web_contents_;
51 } 78 }
52 79
53 void WebView::CreateWebContentsWithSiteInstance( 80 void WebView::CreateWebContentsWithSiteInstance(
54 content::SiteInstance* site_instance) { 81 content::SiteInstance* site_instance) {
55 if (!web_contents_) { 82 if (!web_contents_) {
56 wc_owner_.reset(CreateWebContents(browser_context_, site_instance)); 83 wc_owner_.reset(CreateWebContents(browser_context_, site_instance));
57 web_contents_ = wc_owner_.get(); 84 web_contents_ = wc_owner_.get();
58 web_contents_->SetDelegate(this); 85 web_contents_->SetDelegate(this);
59 AttachWebContents(); 86 AttachWebContents();
60 } 87 }
61 } 88 }
62 89
63 void WebView::SetWebContents(content::WebContents* web_contents) { 90 void WebView::SetWebContents(content::WebContents* web_contents) {
64 if (web_contents == web_contents_) 91 if (web_contents == web_contents_)
65 return; 92 return;
66 DetachWebContents(); 93 DetachWebContents();
67 wc_owner_.reset(); 94 if (wc_owner_ != web_contents)
95 wc_owner_.reset();
68 web_contents_ = web_contents; 96 web_contents_ = web_contents;
97 if (fullscreen_observer_) {
98 fullscreen_observer_->Observe(web_contents_);
99 is_embedding_fullscreen_widget_ =
100 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
101 } else {
102 is_embedding_fullscreen_widget_ = false;
103 }
69 AttachWebContents(); 104 AttachWebContents();
70 } 105 }
71 106
107 void WebView::SetEmbedFullscreenWidgetMode(bool enable) {
108 bool should_be_embedded = enable;
109 if (!fullscreen_observer_ && enable) {
110 DCHECK(!is_embedding_fullscreen_widget_);
111 fullscreen_observer_.reset(new FullscreenObserver(this));
112 fullscreen_observer_->Observe(web_contents_);
113 should_be_embedded =
114 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
115 } else if (fullscreen_observer_ && !enable) {
116 fullscreen_observer_.reset();
117 }
118 if (should_be_embedded != is_embedding_fullscreen_widget_)
119 ReattachForFullscreenChange(should_be_embedded);
120 }
121
72 void WebView::LoadInitialURL(const GURL& url) { 122 void WebView::LoadInitialURL(const GURL& url) {
73 GetWebContents()->GetController().LoadURL( 123 GetWebContents()->GetController().LoadURL(
74 url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL, 124 url, content::Referrer(), content::PAGE_TRANSITION_AUTO_TOPLEVEL,
75 std::string()); 125 std::string());
76 } 126 }
77 127
78 void WebView::SetFastResize(bool fast_resize) { 128 void WebView::SetFastResize(bool fast_resize) {
79 wcv_holder_->set_fast_resize(fast_resize); 129 wcv_holder_->set_fast_resize(fast_resize);
80 } 130 }
81 131
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 return web_contents_ && !web_contents_->IsCrashed(); 169 return web_contents_ && !web_contents_->IsCrashed();
120 } 170 }
121 171
122 bool WebView::IsFocusable() const { 172 bool WebView::IsFocusable() const {
123 // We need to be focusable when our contents is not a view hierarchy, as 173 // We need to be focusable when our contents is not a view hierarchy, as
124 // clicking on the contents needs to focus us. 174 // clicking on the contents needs to focus us.
125 return !!web_contents_; 175 return !!web_contents_;
126 } 176 }
127 177
128 void WebView::OnFocus() { 178 void WebView::OnFocus() {
129 if (web_contents_) 179 if (!web_contents_)
180 return;
181 if (is_embedding_fullscreen_widget_) {
182 content::RenderWidgetHostView* const current_fs_view =
183 web_contents_->GetFullscreenRenderWidgetHostView();
184 if (current_fs_view)
185 current_fs_view->GetRenderWidgetHost()->Focus();
186 } else {
130 web_contents_->GetView()->Focus(); 187 web_contents_->GetView()->Focus();
188 }
131 } 189 }
132 190
133 void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) { 191 void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
134 if (web_contents_) 192 if (web_contents_)
135 web_contents_->FocusThroughTabTraversal(reverse); 193 web_contents_->FocusThroughTabTraversal(reverse);
136 } 194 }
137 195
138 void WebView::GetAccessibleState(ui::AccessibleViewState* state) { 196 void WebView::GetAccessibleState(ui::AccessibleViewState* state) {
139 state->role = ui::AccessibilityTypes::ROLE_GROUPING; 197 state->role = ui::AccessibilityTypes::ROLE_GROUPING;
140 } 198 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 237
180 //////////////////////////////////////////////////////////////////////////////// 238 ////////////////////////////////////////////////////////////////////////////////
181 // WebView, content::WebContentsDelegate implementation: 239 // WebView, content::WebContentsDelegate implementation:
182 240
183 void WebView::WebContentsFocused(content::WebContents* web_contents) { 241 void WebView::WebContentsFocused(content::WebContents* web_contents) {
184 DCHECK(wc_owner_.get()); 242 DCHECK(wc_owner_.get());
185 // The WebView is only the delegate of WebContentses it creates itself. 243 // The WebView is only the delegate of WebContentses it creates itself.
186 OnWebContentsFocused(web_contents_); 244 OnWebContentsFocused(web_contents_);
187 } 245 }
188 246
247 bool WebView::EmbedsFullscreenWidget() const {
248 DCHECK(wc_owner_.get());
249 return !!fullscreen_observer_;
250 }
251
189 //////////////////////////////////////////////////////////////////////////////// 252 ////////////////////////////////////////////////////////////////////////////////
190 // WebView, private: 253 // WebView, private:
191 254
192 void WebView::AttachWebContents() { 255 void WebView::AttachWebContents() {
193 // Prevents attachment if the WebView isn't already in a Widget, or it's 256 // Prevents attachment if the WebView isn't already in a Widget, or it's
194 // already attached. 257 // already attached.
195 if (!GetWidget() || !web_contents_ || 258 if (!GetWidget() || !web_contents_)
196 wcv_holder_->native_view() == web_contents_->GetView()->GetNativeView()) {
197 return; 259 return;
260
261 const gfx::NativeView view_to_attach = is_embedding_fullscreen_widget_ ?
262 web_contents_->GetFullscreenRenderWidgetHostView()->GetNativeView() :
263 web_contents_->GetView()->GetNativeView();
264 if (wcv_holder_->native_view() == view_to_attach)
265 return;
266 wcv_holder_->Attach(view_to_attach);
267
268 // The view will not be focused automatically when it is attached, so we need
269 // to pass on focus to it if the FocusManager thinks the view is focused. Note
270 // that not every Widget has a focus manager.
271 FocusManager* focus_manager = GetFocusManager();
272 if (focus_manager && focus_manager->GetFocusedView() == this) {
273 if (is_embedding_fullscreen_widget_)
274 web_contents_->GetFullscreenRenderWidgetHostView()->Focus();
275 else
276 web_contents_->GetView()->Focus();
198 } 277 }
199 278
200 if (web_contents_) { 279 registrar_.Add(
201 wcv_holder_->Attach(web_contents_->GetView()->GetNativeView()); 280 this,
202 281 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
203 // The WebContentsView will not be focused automatically when it is 282 content::Source<content::NavigationController>(
204 // attached, so we need to pass on focus to it if the FocusManager thinks 283 &web_contents_->GetController()));
205 // the WebView is focused. Note that not every Widget has a focus manager. 284 registrar_.Add(
206 FocusManager* focus_manager = GetFocusManager(); 285 this,
207 if (focus_manager && focus_manager->GetFocusedView() == this) 286 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
208 web_contents_->GetView()->Focus(); 287 content::Source<content::WebContents>(web_contents_));
209
210 registrar_.Add(
211 this,
212 content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
213 content::Source<content::NavigationController>(
214 &web_contents_->GetController()));
215 registrar_.Add(
216 this,
217 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
218 content::Source<content::WebContents>(web_contents_));
219 }
220 288
221 #if defined(OS_WIN) && defined(USE_AURA) 289 #if defined(OS_WIN) && defined(USE_AURA)
222 web_contents_->SetParentNativeViewAccessible( 290 if (!is_embedding_fullscreen_widget_) {
223 parent()->GetNativeViewAccessible()); 291 web_contents_->SetParentNativeViewAccessible(
292 parent()->GetNativeViewAccessible());
293 }
224 #endif 294 #endif
225 } 295 }
226 296
227 void WebView::DetachWebContents() { 297 void WebView::DetachWebContents() {
228 if (web_contents_) { 298 if (web_contents_) {
229 wcv_holder_->Detach(); 299 wcv_holder_->Detach();
230 #if defined(OS_WIN) && !defined(USE_AURA) 300 #if defined(OS_WIN)
231 // TODO(beng): This should either not be necessary, or be done implicitly by 301 if (!is_embedding_fullscreen_widget_) {
232 // NativeViewHostWin on Detach(). As it stands, this is needed so that the 302 #if !defined(USE_AURA)
233 // view of the detached contents knows to tell the renderer it's been 303 // TODO(beng): This should either not be necessary, or be done implicitly
234 // hidden. 304 // by NativeViewHostWin on Detach(). As it stands, this is needed so that
235 // 305 // the of the detached contents knows to tell the renderer it's been
236 // Moving this out of here would also mean we wouldn't be potentially 306 // hidden.
237 // calling member functions on a half-destroyed WebContents. 307 //
238 ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE); 308 // Moving this out of here would also mean we wouldn't be potentially
239 #elif defined(OS_WIN) && defined(USE_AURA) 309 // calling member functions on a half-destroyed WebContents.
240 web_contents_->SetParentNativeViewAccessible(NULL); 310 ShowWindow(web_contents_->GetView()->GetNativeView(), SW_HIDE);
311 #else
312 web_contents_->SetParentNativeViewAccessible(NULL);
313 #endif
314 }
241 #endif 315 #endif
242 } 316 }
243 registrar_.RemoveAll(); 317 registrar_.RemoveAll();
244 } 318 }
245 319
320 void WebView::ReattachForFullscreenChange(bool enter_fullscreen) {
321 DetachWebContents();
322 is_embedding_fullscreen_widget_ = enter_fullscreen &&
323 web_contents_ && web_contents_->GetFullscreenRenderWidgetHostView();
324 AttachWebContents();
325 }
326
246 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host, 327 void WebView::RenderViewHostChanged(content::RenderViewHost* old_host,
247 content::RenderViewHost* new_host) { 328 content::RenderViewHost* new_host) {
248 if (GetFocusManager()->GetFocusedView() == this) 329 if (GetFocusManager()->GetFocusedView() == this)
249 web_contents_->GetView()->Focus(); 330 web_contents_->GetView()->Focus();
250 } 331 }
251 332
252 void WebView::WebContentsDestroyed(content::WebContents* web_contents) { 333 void WebView::WebContentsDestroyed(content::WebContents* web_contents) {
253 DCHECK(web_contents == web_contents_); 334 DCHECK(web_contents == web_contents_);
254 SetWebContents(NULL); 335 SetWebContents(NULL);
255 } 336 }
(...skipping 10 matching lines...) Expand all
266 if (!contents) { 347 if (!contents) {
267 content::WebContents::CreateParams create_params( 348 content::WebContents::CreateParams create_params(
268 browser_context, site_instance); 349 browser_context, site_instance);
269 return content::WebContents::Create(create_params); 350 return content::WebContents::Create(create_params);
270 } 351 }
271 352
272 return contents; 353 return contents;
273 } 354 }
274 355
275 } // namespace views 356 } // namespace views
OLDNEW
« ui/views/controls/webview/webview.h ('K') | « ui/views/controls/webview/webview.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698