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

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: Address nasko@ comments. Created 4 years, 4 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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 identifier(identifier) { 330 identifier(identifier) {
331 } 331 }
332 332
333 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() { 333 WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() {
334 } 334 }
335 335
336 // WebContentsImpl::WebContentsTreeNode ---------------------------------------- 336 // WebContentsImpl::WebContentsTreeNode ----------------------------------------
337 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode() 337 WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode()
338 : outer_web_contents_(nullptr), 338 : outer_web_contents_(nullptr),
339 outer_contents_frame_tree_node_id_( 339 outer_contents_frame_tree_node_id_(
340 FrameTreeNode::kFrameTreeNodeInvalidId) { 340 FrameTreeNode::kFrameTreeNodeInvalidId),
341 } 341 focused_web_contents_(nullptr) {}
342 342
343 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() { 343 WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
344 // Remove child pointer from our parent. 344 // Remove child pointer from our parent.
345 if (outer_web_contents_) { 345 if (outer_web_contents_) {
346 ChildrenSet& child_ptrs_in_parent = 346 ChildrenSet& child_ptrs_in_parent =
347 outer_web_contents_->node_->inner_web_contents_tree_nodes_; 347 outer_web_contents_->node_->inner_web_contents_tree_nodes_;
348 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this); 348 ChildrenSet::iterator iter = child_ptrs_in_parent.find(this);
349 DCHECK(iter != child_ptrs_in_parent.end()); 349 DCHECK(iter != child_ptrs_in_parent.end());
350 child_ptrs_in_parent.erase(this); 350 child_ptrs_in_parent.erase(iter);
351 } 351 }
352 352
353 // Remove parent pointers from our children. 353 // Remove parent pointers from our children.
354 // TODO(lazyboy): We should destroy the children WebContentses too. If the 354 // TODO(lazyboy): We should destroy the children WebContentses too. If the
355 // children do not manage their own lifetime, then we would leak their 355 // children do not manage their own lifetime, then we would leak their
356 // WebContentses. 356 // WebContentses.
357 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_) 357 for (WebContentsTreeNode* child : inner_web_contents_tree_nodes_)
358 child->outer_web_contents_ = nullptr; 358 child->outer_web_contents_ = nullptr;
359 } 359 }
360 360
361 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents( 361 void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
362 WebContentsImpl* outer_web_contents, 362 WebContentsImpl* outer_web_contents,
363 RenderFrameHostImpl* outer_contents_frame) { 363 RenderFrameHostImpl* outer_contents_frame) {
364 DCHECK(!focused_web_contents_) << "Should not attach a root node.";
364 outer_web_contents_ = outer_web_contents; 365 outer_web_contents_ = outer_web_contents;
365 outer_contents_frame_tree_node_id_ = 366 outer_contents_frame_tree_node_id_ =
366 outer_contents_frame->frame_tree_node()->frame_tree_node_id(); 367 outer_contents_frame->frame_tree_node()->frame_tree_node_id();
367 368
368 if (!outer_web_contents_->node_) 369 if (!outer_web_contents_->node_) {
370 // This will only be reached when creating a new WebContents tree.
371 // Initialize the root of this tree and set it as focused.
369 outer_web_contents_->node_.reset(new WebContentsTreeNode()); 372 outer_web_contents_->node_.reset(new WebContentsTreeNode());
373 outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_);
374 }
370 375
371 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this); 376 outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this);
372 } 377 }
373 378
379 void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents(
380 WebContentsImpl* web_contents) {
381 DCHECK(!outer_web_contents())
382 << "Only the outermost WebContents tracks focus.";
383 focused_web_contents_ = web_contents;
384 }
385
374 // WebContentsImpl ------------------------------------------------------------- 386 // WebContentsImpl -------------------------------------------------------------
375 387
376 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) 388 WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
377 : delegate_(NULL), 389 : delegate_(NULL),
378 controller_(this, browser_context), 390 controller_(this, browser_context),
379 render_view_host_delegate_view_(NULL), 391 render_view_host_delegate_view_(NULL),
380 created_with_opener_(false), 392 created_with_opener_(false),
381 frame_tree_(new NavigatorImpl(&controller_, this), 393 frame_tree_(new NavigatorImpl(&controller_, this),
382 this, 394 this,
383 this, 395 this,
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 #endif 451 #endif
440 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this)); 452 loader_io_thread_notifier_.reset(new LoaderIOThreadNotifier(this));
441 wake_lock_service_context_.reset(new WakeLockServiceContext(this)); 453 wake_lock_service_context_.reset(new WakeLockServiceContext(this));
442 } 454 }
443 455
444 WebContentsImpl::~WebContentsImpl() { 456 WebContentsImpl::~WebContentsImpl() {
445 is_being_destroyed_ = true; 457 is_being_destroyed_ = true;
446 458
447 rwh_input_event_router_.reset(); 459 rwh_input_event_router_.reset();
448 460
461 WebContentsImpl* outermost = GetOutermostWebContents();
462 if (GetFocusedWebContents() == this && this != outermost) {
463 // If the current WebContents is in focus, unset it.
464 outermost->node_->SetFocusedWebContents(outermost);
465 }
466
449 for (FrameTreeNode* node : frame_tree_.Nodes()) { 467 for (FrameTreeNode* node : frame_tree_.Nodes()) {
450 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs 468 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs
451 // to be shutdown and be deleted as well. 469 // to be shutdown and be deleted as well.
452 node->render_manager()->ClearRFHsPendingShutdown(); 470 node->render_manager()->ClearRFHsPendingShutdown();
453 node->render_manager()->ClearWebUIInstances(); 471 node->render_manager()->ClearWebUIInstances();
454 } 472 }
455 473
456 for (RenderWidgetHostImpl* widget : created_widgets_) 474 for (RenderWidgetHostImpl* widget : created_widgets_)
457 widget->DetachDelegate(); 475 widget->DetachDelegate();
458 created_widgets_.clear(); 476 created_widgets_.clear();
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1803 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( 1821 RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
1804 RenderWidgetHostImpl* receiving_widget) { 1822 RenderWidgetHostImpl* receiving_widget) {
1805 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible()) 1823 if (!SiteIsolationPolicy::AreCrossProcessFramesPossible())
1806 return receiving_widget; 1824 return receiving_widget;
1807 1825
1808 // Events for widgets other than the main frame (e.g., popup menus) should be 1826 // Events for widgets other than the main frame (e.g., popup menus) should be
1809 // forwarded directly to the widget they arrived on. 1827 // forwarded directly to the widget they arrived on.
1810 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost()) 1828 if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
1811 return receiving_widget; 1829 return receiving_widget;
1812 1830
1813 FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame(); 1831 FrameTreeNode* focused_frame =
1832 GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
1814 if (!focused_frame) 1833 if (!focused_frame)
1815 return receiving_widget; 1834 return receiving_widget;
1816 1835
1817 // The view may be null if a subframe's renderer process has crashed while 1836 // The view may be null if a subframe's renderer process has crashed while
1818 // the subframe has focus. Drop the event in that case. Do not give 1837 // the subframe has focus. Drop the event in that case. Do not give
1819 // it to the main frame, so that the user doesn't unexpectedly type into the 1838 // it to the main frame, so that the user doesn't unexpectedly type into the
1820 // wrong frame if a focused subframe renderer crashes while they type. 1839 // wrong frame if a focused subframe renderer crashes while they type.
1821 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); 1840 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
1822 if (!view) 1841 if (!view)
1823 return nullptr; 1842 return nullptr;
(...skipping 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 if (delegate_) 4187 if (delegate_)
4169 return delegate_->GetRootWindowResizerRect(); 4188 return delegate_->GetRootWindowResizerRect();
4170 return gfx::Rect(); 4189 return gfx::Rect();
4171 } 4190 }
4172 4191
4173 void WebContentsImpl::RemoveBrowserPluginEmbedder() { 4192 void WebContentsImpl::RemoveBrowserPluginEmbedder() {
4174 if (browser_plugin_embedder_) 4193 if (browser_plugin_embedder_)
4175 browser_plugin_embedder_.reset(); 4194 browser_plugin_embedder_.reset();
4176 } 4195 }
4177 4196
4197 WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
4198 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4199 if (node_)
4200 return node_->outer_web_contents();
4201 } else {
4202 if (GetBrowserPluginGuest())
4203 return GetBrowserPluginGuest()->embedder_web_contents();
4204 }
4205 return nullptr;
4206 }
4207
4208 WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
4209 // There is no inner or outer web contents.
4210 if (!node_ && !GetBrowserPluginGuest())
4211 return this;
4212
4213 // We may need to create a node_ on the outermost contents in the
4214 // BrowserPlugin case.
4215 WebContentsImpl* outermost = GetOutermostWebContents();
4216 if (!outermost->node_) {
4217 outermost->node_.reset(new WebContentsTreeNode());
4218 outermost->node_->SetFocusedWebContents(outermost);
4219 }
4220 return outermost->node_->focused_web_contents();
4221 }
4222
4223 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
4224 WebContentsImpl* root = this;
4225 while (root->GetOuterWebContents())
4226 root = root->GetOuterWebContents();
4227 return root;
4228 }
4229
4178 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { 4230 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
4179 // Don't send notifications if we are just creating a swapped-out RVH for 4231 // Don't send notifications if we are just creating a swapped-out RVH for
4180 // the opener chain. These won't be used for view-source or WebUI, so it's 4232 // the opener chain. These won't be used for view-source or WebUI, so it's
4181 // ok to return early. 4233 // ok to return early.
4182 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active()) 4234 if (!static_cast<RenderViewHostImpl*>(render_view_host)->is_active())
4183 return; 4235 return;
4184 4236
4185 if (delegate_) 4237 if (delegate_)
4186 view_->SetOverscrollControllerEnabled(CanOverscrollContent()); 4238 view_->SetOverscrollControllerEnabled(CanOverscrollContent());
4187 4239
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
4570 GetSiteInstance()); 4622 GetSiteInstance());
4571 } else { 4623 } else {
4572 RenderFrameHostImpl* source_rfhi = 4624 RenderFrameHostImpl* source_rfhi =
4573 static_cast<RenderFrameHostImpl*>(source_rfh); 4625 static_cast<RenderFrameHostImpl*>(source_rfh);
4574 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( 4626 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies(
4575 GetSiteInstance(), nullptr); 4627 GetSiteInstance(), nullptr);
4576 } 4628 }
4577 } 4629 }
4578 } 4630 }
4579 4631
4632 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
4633 SiteInstance* source) {
4634 if (!BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4635 frame_tree_.SetFocusedFrame(node, source);
4636 return;
4637 }
4638
4639 // 1. Find old focused frame and unfocus it.
4640 // 2. Focus the new frame in the current FrameTree.
4641 // 3. Set current WebContents as focused.
4642 WebContentsImpl* old_focused_contents = GetFocusedWebContents();
4643 if (old_focused_contents != this) {
4644 // Focus is moving between frame trees, unfocus the frame in the old tree.
4645 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source);
4646 GetOutermostWebContents()->node_->SetFocusedWebContents(this);
4647 }
4648
4649 frame_tree_.SetFocusedFrame(node, source);
4650
4651 // TODO(avallee): Remove this once page focus is fixed.
4652 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost();
4653 if (rwh && old_focused_contents != this &&
4654 BrowserPluginGuestMode::UseCrossProcessFramesForGuests())
4655 rwh->Focus();
4656 }
4657
4580 bool WebContentsImpl::AddMessageToConsole(int32_t level, 4658 bool WebContentsImpl::AddMessageToConsole(int32_t level,
4581 const base::string16& message, 4659 const base::string16& message,
4582 int32_t line_no, 4660 int32_t line_no,
4583 const base::string16& source_id) { 4661 const base::string16& source_id) {
4584 if (!delegate_) 4662 if (!delegate_)
4585 return false; 4663 return false;
4586 return delegate_->AddMessageToConsole(this, level, message, line_no, 4664 return delegate_->AddMessageToConsole(this, level, message, line_no,
4587 source_id); 4665 source_id);
4588 } 4666 }
4589 4667
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
4953 if (node_ && node_->outer_web_contents()) 5031 if (node_ && node_->outer_web_contents())
4954 return node_->outer_contents_frame_tree_node_id(); 5032 return node_->outer_contents_frame_tree_node_id();
4955 5033
4956 return FrameTreeNode::kFrameTreeNodeInvalidId; 5034 return FrameTreeNode::kFrameTreeNodeInvalidId;
4957 } 5035 }
4958 5036
4959 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const { 5037 RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
4960 return frame_tree_.root()->render_manager(); 5038 return frame_tree_.root()->render_manager();
4961 } 5039 }
4962 5040
4963 WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
4964 if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
4965 if (node_)
4966 return node_->outer_web_contents();
4967 } else {
4968 if (GetBrowserPluginGuest())
4969 return GetBrowserPluginGuest()->embedder_web_contents();
4970 }
4971 return nullptr;
4972 }
4973
4974 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { 5041 BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
4975 return browser_plugin_guest_.get(); 5042 return browser_plugin_guest_.get();
4976 } 5043 }
4977 5044
4978 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) { 5045 void WebContentsImpl::SetBrowserPluginGuest(BrowserPluginGuest* guest) {
4979 CHECK(!browser_plugin_guest_); 5046 CHECK(!browser_plugin_guest_);
4980 CHECK(guest); 5047 CHECK(guest);
4981 browser_plugin_guest_.reset(guest); 5048 browser_plugin_guest_.reset(guest);
4982 } 5049 }
4983 5050
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5021 if (controller) { 5088 if (controller) {
5022 web_ui->AddMessageHandler(new GenericHandler()); 5089 web_ui->AddMessageHandler(new GenericHandler());
5023 web_ui->SetController(controller); 5090 web_ui->SetController(controller);
5024 return web_ui; 5091 return web_ui;
5025 } 5092 }
5026 5093
5027 delete web_ui; 5094 delete web_ui;
5028 return NULL; 5095 return NULL;
5029 } 5096 }
5030 5097
5031 // TODO(paulmeyer): This method will not be used until find-in-page across
5032 // GuestViews is implemented.
5033 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
5034 // Find the outer-most WebContents.
5035 WebContentsImpl* outermost_web_contents = this;
5036 while (outermost_web_contents->node_ &&
5037 outermost_web_contents->node_->outer_web_contents()) {
5038 outermost_web_contents =
5039 outermost_web_contents->node_->outer_web_contents();
5040 }
5041 return outermost_web_contents;
5042 }
5043
5044 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { 5098 FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() {
5045 // TODO(paulmeyer): This method will need to access (or potentially create) 5099 // TODO(paulmeyer): This method will need to access (or potentially create)
5046 // the FindRequestManager in the outermost WebContents once find-in-page 5100 // the FindRequestManager in the outermost WebContents once find-in-page
5047 // across GuestViews is implemented. 5101 // across GuestViews is implemented.
5048 if (!find_request_manager_) 5102 if (!find_request_manager_)
5049 find_request_manager_.reset(new FindRequestManager(this)); 5103 find_request_manager_.reset(new FindRequestManager(this));
5050 5104
5051 return find_request_manager_.get(); 5105 return find_request_manager_.get();
5052 } 5106 }
5053 5107
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
5153 for (RenderViewHost* render_view_host : render_view_host_set) 5207 for (RenderViewHost* render_view_host : render_view_host_set)
5154 render_view_host->OnWebkitPreferencesChanged(); 5208 render_view_host->OnWebkitPreferencesChanged();
5155 } 5209 }
5156 5210
5157 void WebContentsImpl::SetJavaScriptDialogManagerForTesting( 5211 void WebContentsImpl::SetJavaScriptDialogManagerForTesting(
5158 JavaScriptDialogManager* dialog_manager) { 5212 JavaScriptDialogManager* dialog_manager) {
5159 dialog_manager_ = dialog_manager; 5213 dialog_manager_ = dialog_manager;
5160 } 5214 }
5161 5215
5162 } // namespace content 5216 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/browser/web_contents/web_contents_view_child_frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698