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

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: Simplify approach based on alexmos feedback. Created 4 years, 7 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 : render_process_id(render_process_id), 321 : render_process_id(render_process_id),
322 render_frame_id(render_frame_id), 322 render_frame_id(render_frame_id),
323 chooser(chooser), 323 chooser(chooser),
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 WebContentsImpl* web_contents)
333 : web_contents_(web_contents),
334 outer_web_contents_(nullptr),
333 outer_contents_frame_tree_node_id_( 335 outer_contents_frame_tree_node_id_(
334 FrameTreeNode::kFrameTreeNodeInvalidId) { 336 FrameTreeNode::kFrameTreeNodeInvalidId),
335 } 337 focused_web_contents_(nullptr) {}
336 338
337 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { 339 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
338 // Remove child pointer from our parent. 340 // Remove child pointer from our parent.
339 if (outer_web_contents_) { 341 if (outer_web_contents_) {
340 ChildrenSet& child_ptrs_in_parent = 342 ChildrenMap& child_ptrs_in_parent =
341 outer_web_contents_->node_->inner_web_contents_tree_nodes_; 343 outer_web_contents_->node_->inner_web_contents_tree_nodes_;
342 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); 344 ChildrenMap::iterator iter =
345 child_ptrs_in_parent.find(outer_contents_frame_tree_node_id_);
343 DCHECK(iter != child_ptrs_in_parent.end()); 346 DCHECK(iter != child_ptrs_in_parent.end());
344 child_ptrs_in_parent.erase(this); 347 child_ptrs_in_parent.erase(iter);
345 } 348 }
346 349
347 // Remove parent pointers from our children. 350 // Remove parent pointers from our children.
348 // TODO(lazyboy): We should destroy the children WebContentses too. If the 351 // TODO(lazyboy): We should destroy the children WebContentses too. If the
349 // children do not manage their own lifetime, then we would leak their 352 // children do not manage their own lifetime, then we would leak their
350 // WebContentses. 353 // WebContentses.
351 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) 354 for (auto& child : inner_web_contents_tree_nodes_)
352 child->outer_web_contents_ = nullptr; 355 child.second->outer_web_contents_ = nullptr;
353 } 356 }
354 357
355 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( 358 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
356 WebContentsImpl* outer_web_contents, 359 WebContentsImpl* outer_web_contents,
357 RenderFrameHostImpl* outer_contents_frame) { 360 RenderFrameHostImpl* outer_contents_frame) {
361 DCHECK(!focused_web_contents_) << "Should not attach a root node.";
358 outer_web_contents_ = outer_web_contents; 362 outer_web_contents_ = outer_web_contents;
359 outer_contents_frame_tree_node_id_ = 363 outer_contents_frame_tree_node_id_ =
360 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); 364 outer_contents_frame->frame_tree_node()->frame_tree_node_id();
361 365
362 if (!outer_web_contents_->node_) 366 if (!outer_web_contents_->node_) {
363 outer_web_contents_->node_.reset(new WebContentsTreeNode()); 367 outer_web_contents_->node_.reset(
368 new WebContentsTreeNode(outer_web_contents_));
369 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_);
alexmos 2016/05/26 00:32:25 nit: maybe add a comment that we can only get here
avallee 2016/06/07 15:37:43 Done. Does it make sense to assert that we don't
alexmos 2016/06/07 22:03:43 Yeah, it seems that the DCHECK should be sufficien
370 }
364 371
365 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); 372 outer_web_contents_->node_
373 ->inner_web_contents_tree_nodes_[outer_contents_frame_tree_node_id_] =
374 this;
375 }
376
377 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents(
378 WebContentsImpl* web_contents) {
379 DCHECK(!outer_web_contents())
380 << "Only the outermost WebContents tracks focus.";
381 focused_web_contents_ = web_contents;
366 } 382 }
367 383
368 // WebContentsImpl ------------------------------------------------------------- 384 // WebContentsImpl -------------------------------------------------------------
369 385
370 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) 386 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
371 : delegate_(NULL), 387 : delegate_(NULL),
372 controller_(this, browser_context), 388 controller_(this, browser_context),
373 render_view_host_delegate_view_(NULL), 389 render_view_host_delegate_view_(NULL),
374 created_with_opener_(false), 390 created_with_opener_(false),
375 frame_tree_(new NavigatorImpl(&controller_, this), 391 frame_tree_(new NavigatorImpl(&controller_, this),
(...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // created. This is needed because the usual initialization happens during 1402 // created. This is needed because the usual initialization happens during
1387 // the first navigation, but when attaching a new window we don't navigate 1403 // the first navigation, but when attaching a new window we don't navigate
1388 // before attaching. If the browser side is already initialized, the calls 1404 // before attaching. If the browser side is already initialized, the calls
1389 // below will just early return. 1405 // below will just early return.
1390 render_manager->InitRenderView(GetRenderViewHost(), nullptr); 1406 render_manager->InitRenderView(GetRenderViewHost(), nullptr);
1391 GetMainFrame()->Init(); 1407 GetMainFrame()->Init();
1392 if (!render_manager->GetRenderWidgetHostView()) 1408 if (!render_manager->GetRenderWidgetHostView())
1393 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost()); 1409 CreateRenderWidgetHostViewForRenderManager(GetRenderViewHost());
1394 1410
1395 // Create a link to our outer WebContents. 1411 // Create a link to our outer WebContents.
1396 node_.reset(new WebContentsTreeNode()); 1412 node_.reset(new WebContentsTreeNode(this));
1397 node_->ConnectToOuterWebContents( 1413 node_->ConnectToOuterWebContents(
1398 static_cast<WebContentsImpl*>(outer_web_contents), 1414 static_cast<WebContentsImpl*>(outer_web_contents),
1399 static_cast<RenderFrameHostImpl*>(outer_contents_frame)); 1415 static_cast<RenderFrameHostImpl*>(outer_contents_frame));
1400 1416
1401 DCHECK(outer_contents_frame); 1417 DCHECK(outer_contents_frame);
1402 1418
1403 // Create a proxy in top-level RenderFrameHostManager, pointing to the 1419 // Create a proxy in top-level RenderFrameHostManager, pointing to the
1404 // SiteInstance of the outer WebContents. The proxy will be used to send 1420 // SiteInstance of the outer WebContents. The proxy will be used to send
1405 // postMessage to the inner WebContents. 1421 // postMessage to the inner WebContents.
1406 render_manager->CreateOuterDelegateProxy( 1422 render_manager->CreateOuterDelegateProxy(
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( 1798 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
1783 RenderWidgetHostImpl* receiving_widget) { 1799 RenderWidgetHostImpl* receiving_widget) {
1784 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) 1800 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
1785 return receiving_widget; 1801 return receiving_widget;
1786 1802
1787 // Events for widgets other than the main frame (e.g., popup menus) should be 1803 // Events for widgets other than the main frame (e.g., popup menus) should be
1788 // forwarded directly to the widget they arrived on. 1804 // forwarded directly to the widget they arrived on.
1789 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) 1805 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
1790 return receiving_widget; 1806 return receiving_widget;
1791 1807
1792 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); 1808 FrameTreeNode* focused_frame =
1809 GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
1793 if (!focused_frame) 1810 if (!focused_frame)
1794 return receiving_widget; 1811 return receiving_widget;
1795 1812
1796 // The view may be null if a subframe's renderer process has crashed while 1813 // 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 1814 // 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 1815 // 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. 1816 // wrong frame if a focused subframe renderer crashes while they type.
1800 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); 1817 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
1801 if (!view) 1818 if (!view)
1802 return nullptr; 1819 return nullptr;
(...skipping 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after
4080 if (delegate_) 4097 if (delegate_)
4081 return delegate_->GetRootWindowResizerRect(); 4098 return delegate_->GetRootWindowResizerRect();
4082 return gfx::Rect(); 4099 return gfx::Rect();
4083 } 4100 }
4084 4101
4085 void WebContentsImpl::RemoveBrowserPluginEmbedder() { 4102 void WebContentsImpl::RemoveBrowserPluginEmbedder() {
4086 if (browser_plugin_embedder_) 4103 if (browser_plugin_embedder_)
4087 browser_plugin_embedder_.reset(); 4104 browser_plugin_embedder_.reset();
4088 } 4105 }
4089 4106
4107 WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
4108 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4109 if (node_)
4110 return node_->outer_web_contents();
4111 } else {
4112 if (GetBrowserPluginGuest())
4113 return GetBrowserPluginGuest()->embedder_web_contents();
4114 }
4115 return nullptr;
4116 }
4117
4118 WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
4119 // There is no inner web contents.
4120 if (!node_) {
4121 return this;
4122 }
4123
4124 // If we've found root by iterating through outer WebContents, root must have
4125 // a valid node_ since the inner WebContents will have created one when
4126 // connecting.
4127 return GetOutermostWebContents()->node_->get_focused_web_contents();
4128 }
4129
4090 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { 4130 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
4091 // Don't send notifications if we are just creating a swapped-out RVH for 4131 // 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 4132 // the opener chain. These won't be used for view-source or WebUI, so it's
4093 // ok to return early. 4133 // ok to return early.
4094 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) 4134 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active())
4095 return; 4135 return;
4096 4136
4097 if (delegate_) 4137 if (delegate_)
4098 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4138 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4099 4139
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
4478 GetSiteInstance()); 4518 GetSiteInstance());
4479 } else { 4519 } else {
4480 RenderFrameHostImpl* source_rfhi = 4520 RenderFrameHostImpl* source_rfhi =
4481 static_cast<RenderFrameHostImpl*>(source_rfh); 4521 static_cast<RenderFrameHostImpl*>(source_rfh);
4482 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( 4522 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies(
4483 GetSiteInstance(), nullptr); 4523 GetSiteInstance(), nullptr);
4484 } 4524 }
4485 } 4525 }
4486 } 4526 }
4487 4527
4528 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
4529 SiteInstance* source) {
4530 // Focus
4531 // 1. Find old focus and unfocus.
4532 // 2. Focus current tree
4533 // 3. Set current contents as focus
alexmos 2016/05/26 00:32:25 a couple of nits (just to be more precise with cla
avallee 2016/06/07 15:37:43 Done.
4534 //
4535 // Find root contents. Find focused contents.
alexmos 2016/05/26 00:32:25 nit: this comment is probably unnecessary (root co
avallee 2016/06/07 15:37:43 Done.
4536 WebContentsImpl* old_focused_contents = GetFocusedWebContents();
4537 if (old_focused_contents != this) {
4538 // Focus is moving between frame trees, unfocus the frame in the old tree.
4539 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source);
4540 GetOutermostWebContents()->node_->SetFocusedWebContents(this);
4541 }
4542
4543 // Notify proxy?
alexmos 2016/05/26 00:32:25 what does this refer to?
avallee 2016/06/07 15:37:43 Mental implementation detail. Should have been rem
4544 frame_tree_.SetFocusedFrame(node, source);
4545
4546 // TODO(avallee): Remove this once page focus is fixed.
4547 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost();
4548 if (rwh)
4549 rwh->Focus();
alexmos 2016/05/26 00:32:25 We don't want this to break default modes in Chrom
alexmos 2016/05/26 00:32:25 I poked at this a bit more to refresh my memory on
avallee 2016/06/07 15:37:43 I've restricted for now. My trial implementation
alexmos 2016/06/07 22:03:43 OK, let's deal with that in a followup CL. It sho
4550 }
4551
4488 bool WebContentsImpl::AddMessageToConsole(int32_t level, 4552 bool WebContentsImpl::AddMessageToConsole(int32_t level,
4489 const base::string16& message, 4553 const base::string16& message,
4490 int32_t line_no, 4554 int32_t line_no,
4491 const base::string16& source_id) { 4555 const base::string16& source_id) {
4492 if (!delegate_) 4556 if (!delegate_)
4493 return false; 4557 return false;
4494 return delegate_->AddMessageToConsole(this, level, message, line_no, 4558 return delegate_->AddMessageToConsole(this, level, message, line_no,
4495 source_id); 4559 source_id);
4496 } 4560 }
4497 4561
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
4855 if (node_ && node_->outer_web_contents()) 4919 if (node_ && node_->outer_web_contents())
4856 return node_->outer_contents_frame_tree_node_id(); 4920 return node_->outer_contents_frame_tree_node_id();
4857 4921
4858 return FrameTreeNode::kFrameTreeNodeInvalidId; 4922 return FrameTreeNode::kFrameTreeNodeInvalidId;
4859 } 4923 }
4860 4924
4861 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { 4925 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
4862 return frame_tree_.root()->render_manager(); 4926 return frame_tree_.root()->render_manager();
4863 } 4927 }
4864 4928
4865 WebContentsImpl* WebContentsImpl::GetOuterWebContents() { 4929 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
alexmos 2016/05/26 00:32:25 nit: prefer to match up the order of all new funct
avallee 2016/06/07 15:37:43 Done.
4866 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) { 4930 WebContentsImpl* root = this;
4867 if (node_) 4931 while (root->GetOuterWebContents())
4868 return node_->outer_web_contents(); 4932 root = root->GetOuterWebContents();
4869 } else { 4933 return root;
4870 if (GetBrowserPluginGuest())
4871 return GetBrowserPluginGuest()->embedder_web_contents();
4872 }
4873 return nullptr;
4874 } 4934 }
4875 4935
4876 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { 4936 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
4877 return browser_plugin_guest_.get(); 4937 return browser_plugin_guest_.get();
4878 } 4938 }
4879 4939
4880 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { 4940 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) {
4881 CHECK(!browser_plugin_guest_); 4941 CHECK(!browser_plugin_guest_);
4882 CHECK(guest); 4942 CHECK(guest);
4883 browser_plugin_guest_.reset(guest); 4943 browser_plugin_guest_.reset(guest);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
5015 for (RenderViewHost* render_view_host : render_view_host_set) 5075 for (RenderViewHost* render_view_host : render_view_host_set)
5016 render_view_host->OnWebkitPreferencesChanged(); 5076 render_view_host->OnWebkitPreferencesChanged();
5017 } 5077 }
5018 5078
5019 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( 5079 void WebContentsImpl::SetJavaScriptDialogManagerForTesting(
5020 JavaScriptDialogManager* dialog_manager) { 5080 JavaScriptDialogManager* dialog_manager) {
5021 dialog_manager_ = dialog_manager; 5081 dialog_manager_ = dialog_manager;
5022 } 5082 }
5023 5083
5024 } // namespace content 5084 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698