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

Side by Side Diff: content/browser/web_contents/web_contents_impl.cc

Issue 1934703002: Fix keyboard focus for OOPIF-<webview>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added test and addressed comments. Created 4 years, 6 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
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 "content/browser/web_contents/web_contents_impl.h" 5 #include "content/browser/web_contents/web_contents_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <cmath> 9 #include <cmath>
10 #include <utility> 10 #include <utility>
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 identifier(identifier) { 324 identifier(identifier) {
325 } 325 }
326 326
327 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { 327 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() {
328 } 328 }
329 329
330 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- 330 // WebContentsImpl::WebContentsTreeNode ----------------------------------------
331 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() 331 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode()
332 : outer_web_contents_(nullptr), 332 : outer_web_contents_(nullptr),
333 outer_contents_frame_tree_node_id_( 333 outer_contents_frame_tree_node_id_(
334 FrameTreeNode::kFrameTreeNodeInvalidId) { 334 FrameTreeNode::kFrameTreeNodeInvalidId),
335 } 335 focused_web_contents_(nullptr) {}
336 336
337 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { 337 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
alexmos 2016/06/07 22:03:43 What will happen if the currently focused WebConte
avallee 2016/06/15 13:32:10 It feels like there should be no element with focu
alexmos 2016/06/24 01:38:49 Acknowledged.
338 // Remove child pointer from our parent. 338 // Remove child pointer from our parent.
339 if (outer_web_contents_) { 339 if (outer_web_contents_) {
340 ChildrenSet& child_ptrs_in_parent = 340 ChildrenSet& child_ptrs_in_parent =
341 outer_web_contents_->node_->inner_web_contents_tree_nodes_; 341 outer_web_contents_->node_->inner_web_contents_tree_nodes_;
342 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); 342 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this);
343 DCHECK(iter != child_ptrs_in_parent.end()); 343 DCHECK(iter != child_ptrs_in_parent.end());
344 child_ptrs_in_parent.erase(this); 344 child_ptrs_in_parent.erase(iter);
345 } 345 }
346 346
347 // Remove parent pointers from our children. 347 // Remove parent pointers from our children.
348 // TODO(lazyboy): We should destroy the children WebContentses too. If the 348 // TODO(lazyboy): We should destroy the children WebContentses too. If the
349 // children do not manage their own lifetime, then we would leak their 349 // children do not manage their own lifetime, then we would leak their
350 // WebContentses. 350 // WebContentses.
351 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) 351 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_)
352 child->outer_web_contents_ = nullptr; 352 child->outer_web_contents_ = nullptr;
353 } 353 }
354 354
355 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( 355 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
356 WebContentsImpl* outer_web_contents, 356 WebContentsImpl* outer_web_contents,
357 RenderFrameHostImpl* outer_contents_frame) { 357 RenderFrameHostImpl* outer_contents_frame) {
358 DCHECK(!focused_web_contents_) << "Should not attach a root node.";
358 outer_web_contents_ = outer_web_contents; 359 outer_web_contents_ = outer_web_contents;
359 outer_contents_frame_tree_node_id_ = 360 outer_contents_frame_tree_node_id_ =
360 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); 361 outer_contents_frame->frame_tree_node()->frame_tree_node_id();
361 362
362 if (!outer_web_contents_->node_) 363 if (!outer_web_contents_->node_) {
364 // This will reached when connecting into a new WebContents tree. We
alexmos 2016/06/07 22:03:43 s/will reached/will only be reached/
avallee 2016/06/15 13:32:10 Done.
365 // implicitly set the root of this tree as being focused since this is
alexmos 2016/06/07 22:03:43 The part after "since" was difficult to parse ("ca
avallee 2016/06/15 13:32:10 Done.
366 // called in the process of creating an inner WebContents so I couldn't be
367 // focused yet.
363 outer_web_contents_->node_.reset(new WebContentsTreeNode()); 368 outer_web_contents_->node_.reset(new WebContentsTreeNode());
369 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_);
370 }
364 371
365 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); 372 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this);
366 } 373 }
367 374
375 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents(
376 WebContentsImpl* web_contents) {
377 DCHECK(!outer_web_contents())
378 << "Only the outermost WebContents tracks focus.";
379 focused_web_contents_ = web_contents;
380 }
381
368 // WebContentsImpl ------------------------------------------------------------- 382 // WebContentsImpl -------------------------------------------------------------
369 383
370 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) 384 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
371 : delegate_(NULL), 385 : delegate_(NULL),
372 controller_(this, browser_context), 386 controller_(this, browser_context),
373 render_view_host_delegate_view_(NULL), 387 render_view_host_delegate_view_(NULL),
374 created_with_opener_(false), 388 created_with_opener_(false),
375 frame_tree_(new NavigatorImpl(&controller_, this), 389 frame_tree_(new NavigatorImpl(&controller_, this),
376 this, 390 this,
377 this, 391 this,
(...skipping 1404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( 1796 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
1783 RenderWidgetHostImpl* receiving_widget) { 1797 RenderWidgetHostImpl* receiving_widget) {
1784 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) 1798 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
1785 return receiving_widget; 1799 return receiving_widget;
1786 1800
1787 // Events for widgets other than the main frame (e.g., popup menus) should be 1801 // Events for widgets other than the main frame (e.g., popup menus) should be
1788 // forwarded directly to the widget they arrived on. 1802 // forwarded directly to the widget they arrived on.
1789 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) 1803 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
1790 return receiving_widget; 1804 return receiving_widget;
1791 1805
1792 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); 1806 FrameTreeNode* focused_frame =
1807 GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
1793 if (!focused_frame) 1808 if (!focused_frame)
1794 return receiving_widget; 1809 return receiving_widget;
1795 1810
1796 // The view may be null if a subframe's renderer process has crashed while 1811 // The view may be null if a subframe's renderer process has crashed while
1797 // the subframe has focus. Drop the event in that case. Do not give 1812 // the subframe has focus. Drop the event in that case. Do not give
1798 // it to the main frame, so that the user doesn't unexpectedly type into the 1813 // it to the main frame, so that the user doesn't unexpectedly type into the
1799 // wrong frame if a focused subframe renderer crashes while they type. 1814 // wrong frame if a focused subframe renderer crashes while they type.
1800 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); 1815 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
1801 if (!view) 1816 if (!view)
1802 return nullptr; 1817 return nullptr;
(...skipping 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after
4080 if (delegate_) 4095 if (delegate_)
4081 return delegate_->GetRootWindowResizerRect(); 4096 return delegate_->GetRootWindowResizerRect();
4082 return gfx::Rect(); 4097 return gfx::Rect();
4083 } 4098 }
4084 4099
4085 void WebContentsImpl::RemoveBrowserPluginEmbedder() { 4100 void WebContentsImpl::RemoveBrowserPluginEmbedder() {
4086 if (browser_plugin_embedder_) 4101 if (browser_plugin_embedder_)
4087 browser_plugin_embedder_.reset(); 4102 browser_plugin_embedder_.reset();
4088 } 4103 }
4089 4104
4105 WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
4106 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4107 if (node_)
4108 return node_->outer_web_contents();
4109 } else {
4110 if (GetBrowserPluginGuest())
4111 return GetBrowserPluginGuest()->embedder_web_contents();
4112 }
4113 return nullptr;
4114 }
4115
4116 WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
4117 // There is no inner web contents.
4118 if (!node_) {
4119 return this;
4120 }
4121
4122 // If we've found root by iterating through outer WebContents, root must have
4123 // a valid node_ since the inner WebContents will have created one when
4124 // connecting.
4125 return GetOutermostWebContents()->node_->focused_web_contents();
4126 }
4127
4128 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
4129 WebContentsImpl* root = this;
4130 while (root->GetOuterWebContents())
4131 root = root->GetOuterWebContents();
4132 return root;
4133 }
4134
4090 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { 4135 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
4091 // Don't send notifications if we are just creating a swapped-out RVH for 4136 // Don't send notifications if we are just creating a swapped-out RVH for
4092 // the opener chain. These won't be used for view-source or WebUI, so it's 4137 // the opener chain. These won't be used for view-source or WebUI, so it's
4093 // ok to return early. 4138 // ok to return early.
4094 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) 4139 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active())
4095 return; 4140 return;
4096 4141
4097 if (delegate_) 4142 if (delegate_)
4098 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4143 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4099 4144
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
4478 GetSiteInstance()); 4523 GetSiteInstance());
4479 } else { 4524 } else {
4480 RenderFrameHostImpl* source_rfhi = 4525 RenderFrameHostImpl* source_rfhi =
4481 static_cast<RenderFrameHostImpl*>(source_rfh); 4526 static_cast<RenderFrameHostImpl*>(source_rfh);
4482 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( 4527 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies(
4483 GetSiteInstance(), nullptr); 4528 GetSiteInstance(), nullptr);
4484 } 4529 }
4485 } 4530 }
4486 } 4531 }
4487 4532
4533 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
4534 SiteInstance* source) {
4535 // 1. Find old focused frame and unfocus it.
4536 // 2. Focus the new frame in the current FrameTree.
4537 // 3. Set current WebContents as focused.
4538 WebContentsImpl* old_focused_contents = GetFocusedWebContents();
4539 if (old_focused_contents != this) {
4540 // Focus is moving between frame trees, unfocus the frame in the old tree.
4541 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source);
4542 GetOutermostWebContents()->node_->SetFocusedWebContents(this);
4543 }
4544
4545 frame_tree_.SetFocusedFrame(node, source);
4546
4547 // TODO(avallee): Remove this once page focus is fixed.
4548 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost();
4549 if (rwh && old_focused_contents != this &&
4550 BrowserPluginGuestMode::UseCrossProcessFramesForGuests())
4551 rwh->Focus();
4552 }
4553
4488 bool WebContentsImpl::AddMessageToConsole(int32_t level, 4554 bool WebContentsImpl::AddMessageToConsole(int32_t level,
4489 const base::string16& message, 4555 const base::string16& message,
4490 int32_t line_no, 4556 int32_t line_no,
4491 const base::string16& source_id) { 4557 const base::string16& source_id) {
4492 if (!delegate_) 4558 if (!delegate_)
4493 return false; 4559 return false;
4494 return delegate_->AddMessageToConsole(this, level, message, line_no, 4560 return delegate_->AddMessageToConsole(this, level, message, line_no,
4495 source_id); 4561 source_id);
4496 } 4562 }
4497 4563
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
4855 if (node_ && node_->outer_web_contents()) 4921 if (node_ && node_->outer_web_contents())
4856 return node_->outer_contents_frame_tree_node_id(); 4922 return node_->outer_contents_frame_tree_node_id();
4857 4923
4858 return FrameTreeNode::kFrameTreeNodeInvalidId; 4924 return FrameTreeNode::kFrameTreeNodeInvalidId;
4859 } 4925 }
4860 4926
4861 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { 4927 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
4862 return frame_tree_.root()->render_manager(); 4928 return frame_tree_.root()->render_manager();
4863 } 4929 }
4864 4930
4865 WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
4866 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4867 if (node_)
4868 return node_->outer_web_contents();
4869 } else {
4870 if (GetBrowserPluginGuest())
4871 return GetBrowserPluginGuest()->embedder_web_contents();
4872 }
4873 return nullptr;
4874 }
4875
4876 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { 4931 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
4877 return browser_plugin_guest_.get(); 4932 return browser_plugin_guest_.get();
4878 } 4933 }
4879 4934
4880 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { 4935 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) {
4881 CHECK(!browser_plugin_guest_); 4936 CHECK(!browser_plugin_guest_);
4882 CHECK(guest); 4937 CHECK(guest);
4883 browser_plugin_guest_.reset(guest); 4938 browser_plugin_guest_.reset(guest);
4884 } 4939 }
4885 4940
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
5015 for (RenderViewHost* render_view_host : render_view_host_set) 5070 for (RenderViewHost* render_view_host : render_view_host_set)
5016 render_view_host->OnWebkitPreferencesChanged(); 5071 render_view_host->OnWebkitPreferencesChanged();
5017 } 5072 }
5018 5073
5019 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( 5074 void WebContentsImpl::SetJavaScriptDialogManagerForTesting(
5020 JavaScriptDialogManager* dialog_manager) { 5075 JavaScriptDialogManager* dialog_manager) {
5021 dialog_manager_ = dialog_manager; 5076 dialog_manager_ = dialog_manager;
5022 } 5077 }
5023 5078
5024 } // namespace content 5079 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698