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

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

Issue 2451143003: <webview>: Correctly shift focus between WebContents. (Closed)
Patch Set: Add fix for MacOS hang. Created 4 years, 1 month 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 475
476 WebContentsImpl::~WebContentsImpl() { 476 WebContentsImpl::~WebContentsImpl() {
477 is_being_destroyed_ = true; 477 is_being_destroyed_ = true;
478 478
479 rwh_input_event_router_.reset(); 479 rwh_input_event_router_.reset();
480 480
481 for (auto& entry : binding_sets_) 481 for (auto& entry : binding_sets_)
482 entry.second->CloseAllBindings(); 482 entry.second->CloseAllBindings();
483 483
484 WebContentsImpl* outermost = GetOutermostWebContents(); 484 WebContentsImpl* outermost = GetOutermostWebContents();
485 if (GetFocusedWebContents() == this && this != outermost) { 485 if (this != outermost && ContainsOrIsFocusedWebContents()) {
486 // If the current WebContents is in focus, unset it. 486 // If the current WebContents is in focus, unset it.
487 outermost->node_->SetFocusedWebContents(outermost); 487 outermost->SetAsFocusedWebContentsIfNecessary();
488 } 488 }
489 489
490 for (FrameTreeNode* node : frame_tree_.Nodes()) { 490 for (FrameTreeNode* node : frame_tree_.Nodes()) {
491 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs 491 // Delete all RFHs pending shutdown, which will lead the corresponding RVHs
492 // to be shutdown and be deleted as well. 492 // to be shutdown and be deleted as well.
493 node->render_manager()->ClearRFHsPendingShutdown(); 493 node->render_manager()->ClearRFHsPendingShutdown();
494 node->render_manager()->ClearWebUIInstances(); 494 node->render_manager()->ClearWebUIInstances();
495 } 495 }
496 496
497 for (RenderWidgetHostImpl* widget : created_widgets_) 497 for (RenderWidgetHostImpl* widget : created_widgets_)
(...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 // the subframe has focus. Drop the event in that case. Do not give 1863 // the subframe has focus. Drop the event in that case. Do not give
1864 // it to the main frame, so that the user doesn't unexpectedly type into the 1864 // it to the main frame, so that the user doesn't unexpectedly type into the
1865 // wrong frame if a focused subframe renderer crashes while they type. 1865 // wrong frame if a focused subframe renderer crashes while they type.
1866 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); 1866 RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView();
1867 if (!view) 1867 if (!view)
1868 return nullptr; 1868 return nullptr;
1869 1869
1870 return RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); 1870 return RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
1871 } 1871 }
1872 1872
1873 RenderWidgetHostImpl* WebContentsImpl::GetRenderWidgetHostWithPageFocus() {
1874 return GetFocusedWebContents()->GetMainFrame()->GetRenderWidgetHost();
1875 }
1876
1873 void WebContentsImpl::EnterFullscreenMode(const GURL& origin) { 1877 void WebContentsImpl::EnterFullscreenMode(const GURL& origin) {
1874 // This method is being called to enter renderer-initiated fullscreen mode. 1878 // This method is being called to enter renderer-initiated fullscreen mode.
1875 // Make sure any existing fullscreen widget is shut down first. 1879 // Make sure any existing fullscreen widget is shut down first.
1876 RenderWidgetHostView* const widget_view = GetFullscreenRenderWidgetHostView(); 1880 RenderWidgetHostView* const widget_view = GetFullscreenRenderWidgetHostView();
1877 if (widget_view) { 1881 if (widget_view) {
1878 RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost()) 1882 RenderWidgetHostImpl::From(widget_view->GetRenderWidgetHost())
1879 ->ShutdownAndDestroyWidget(true); 1883 ->ShutdownAndDestroyWidget(true);
1880 } 1884 }
1881 1885
1882 if (delegate_) 1886 if (delegate_)
(...skipping 2333 matching lines...) Expand 10 before | Expand all | Expand 10 after
4216 // We may need to create a node_ on the outermost contents in the 4220 // We may need to create a node_ on the outermost contents in the
4217 // BrowserPlugin case. 4221 // BrowserPlugin case.
4218 WebContentsImpl* outermost = GetOutermostWebContents(); 4222 WebContentsImpl* outermost = GetOutermostWebContents();
4219 if (!outermost->node_) { 4223 if (!outermost->node_) {
4220 outermost->node_.reset(new WebContentsTreeNode()); 4224 outermost->node_.reset(new WebContentsTreeNode());
4221 outermost->node_->SetFocusedWebContents(outermost); 4225 outermost->node_->SetFocusedWebContents(outermost);
4222 } 4226 }
4223 return outermost->node_->focused_web_contents(); 4227 return outermost->node_->focused_web_contents();
4224 } 4228 }
4225 4229
4230 bool WebContentsImpl::ContainsOrIsFocusedWebContents() {
4231 for (WebContentsImpl* focused_contents = GetFocusedWebContents();
4232 focused_contents;
4233 focused_contents = focused_contents->GetOuterWebContents()) {
4234 if (focused_contents == this)
4235 return true;
4236 }
4237
4238 return false;
4239 }
4240
4226 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { 4241 WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
4227 WebContentsImpl* root = this; 4242 WebContentsImpl* root = this;
4228 while (root->GetOuterWebContents()) 4243 while (root->GetOuterWebContents())
4229 root = root->GetOuterWebContents(); 4244 root = root->GetOuterWebContents();
4230 return root; 4245 return root;
4231 } 4246 }
4232 4247
4233 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) { 4248 void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
4234 // Don't send notifications if we are just creating a swapped-out RVH for 4249 // Don't send notifications if we are just creating a swapped-out RVH for
4235 // the opener chain. These won't be used for view-source or WebUI, so it's 4250 // the opener chain. These won't be used for view-source or WebUI, so it's
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
4635 GetSiteInstance()); 4650 GetSiteInstance());
4636 } else { 4651 } else {
4637 RenderFrameHostImpl* source_rfhi = 4652 RenderFrameHostImpl* source_rfhi =
4638 static_cast<RenderFrameHostImpl*>(source_rfh); 4653 static_cast<RenderFrameHostImpl*>(source_rfh);
4639 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies( 4654 source_rfhi->frame_tree_node()->render_manager()->CreateOpenerProxies(
4640 GetSiteInstance(), nullptr); 4655 GetSiteInstance(), nullptr);
4641 } 4656 }
4642 } 4657 }
4643 } 4658 }
4644 4659
4660 void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() {
4661 // Only change focus if we are not currently focused.
4662 WebContentsImpl* old_contents = GetFocusedWebContents();
4663 if (old_contents == this)
4664 return;
4665
4666 // Send a page level blur to the old contents so that it displays inactive UI
4667 // and focus this contents to activate it.
4668 if (old_contents)
4669 old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false);
4670 GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true);
4671 GetOutermostWebContents()->node_->SetFocusedWebContents(this);
4672 }
4673
4645 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, 4674 void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
4646 SiteInstance* source) { 4675 SiteInstance* source) {
4647 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { 4676 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) {
4648 frame_tree_.SetFocusedFrame(node, source); 4677 frame_tree_.SetFocusedFrame(node, source);
4649 return; 4678 return;
4650 } 4679 }
4651 4680
4652 // 1. Find old focused frame and unfocus it. 4681 SetAsFocusedWebContentsIfNecessary();
4653 // 2. Focus the new frame in the current FrameTree.
4654 // 3. Set current WebContents as focused.
4655 WebContentsImpl* old_focused_contents = GetFocusedWebContents();
4656 if (old_focused_contents != this) {
4657 // Focus is moving between frame trees, unfocus the frame in the old tree.
4658 old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source);
4659 GetOutermostWebContents()->node_->SetFocusedWebContents(this);
4660 }
4661 4682
4662 frame_tree_.SetFocusedFrame(node, source); 4683 frame_tree_.SetFocusedFrame(node, source);
4663
4664 // TODO(avallee): Remove this once page focus is fixed.
4665 RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost();
4666 if (rwh && old_focused_contents != this)
4667 rwh->Focus();
4668 } 4684 }
4669 4685
4670 bool WebContentsImpl::DidAddMessageToConsole(int32_t level, 4686 bool WebContentsImpl::DidAddMessageToConsole(int32_t level,
4671 const base::string16& message, 4687 const base::string16& message,
4672 int32_t line_no, 4688 int32_t line_no,
4673 const base::string16& source_id) { 4689 const base::string16& source_id) {
4674 if (!delegate_) 4690 if (!delegate_)
4675 return false; 4691 return false;
4676 return delegate_->DidAddMessageToConsole(this, level, message, line_no, 4692 return delegate_->DidAddMessageToConsole(this, level, message, line_no,
4677 source_id); 4693 source_id);
4678 } 4694 }
4679 4695
4680 void WebContentsImpl::OnUserInteraction( 4696 void WebContentsImpl::OnUserInteraction(
4681 RenderWidgetHostImpl* render_widget_host, 4697 RenderWidgetHostImpl* render_widget_host,
4682 const blink::WebInputEvent::Type type) { 4698 const blink::WebInputEvent::Type type) {
4683 // Ignore unless the widget is currently in the frame tree. 4699 // Ignore unless the widget is currently in the frame tree.
4684 if (!HasMatchingWidgetHost(&frame_tree_, render_widget_host)) 4700 if (!HasMatchingWidgetHost(&frame_tree_, render_widget_host))
4685 return; 4701 return;
4686 4702
4687 for (auto& observer : observers_) 4703 for (auto& observer : observers_)
4688 observer.DidGetUserInteraction(type); 4704 observer.DidGetUserInteraction(type);
4689 4705
4690 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); 4706 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
4691 // Exclude scroll events as user gestures for resource load dispatches. 4707 // Exclude scroll events as user gestures for resource load dispatches.
4692 // rdh is NULL in unittests. 4708 // rdh is NULL in unittests.
4693 if (rdh && type != blink::WebInputEvent::MouseWheel) 4709 if (rdh && type != blink::WebInputEvent::MouseWheel)
4694 rdh->OnUserGesture(); 4710 rdh->OnUserGesture();
4695 } 4711 }
4696 4712
4713 void WebContentsImpl::EnsureOwningContentsIsFocused(
4714 RenderWidgetHostImpl* render_widget_host) {
4715 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_)
Charlie Reis 2016/11/16 20:28:23 What's this early return about? Can you clarify w
avallee 2016/11/16 21:18:10 See discussion here: https://codereview.chromium.o
Charlie Reis 2016/11/16 21:51:19 Thanks for adding the comment.
4716 return;
4717
4718 RenderWidgetHostImpl* focused_widget =
4719 GetFocusedRenderWidgetHost(render_widget_host);
4720
4721 if (focused_widget != render_widget_host &&
4722 focused_widget->delegate() != render_widget_host->delegate()) {
4723 SetAsFocusedWebContentsIfNecessary();
4724 }
4725 }
4726
4697 void WebContentsImpl::OnIgnoredUIEvent() { 4727 void WebContentsImpl::OnIgnoredUIEvent() {
4698 // Notify observers. 4728 // Notify observers.
4699 for (auto& observer : observers_) 4729 for (auto& observer : observers_)
4700 observer.DidGetIgnoredUIEvent(); 4730 observer.DidGetIgnoredUIEvent();
4701 } 4731 }
4702 4732
4703 void WebContentsImpl::RendererUnresponsive( 4733 void WebContentsImpl::RendererUnresponsive(
4704 RenderWidgetHostImpl* render_widget_host, 4734 RenderWidgetHostImpl* render_widget_host,
4705 RendererUnresponsiveType type) { 4735 RendererUnresponsiveType type) {
4706 for (auto& observer : observers_) 4736 for (auto& observer : observers_)
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
5227 dialog_manager_ = dialog_manager; 5257 dialog_manager_ = dialog_manager;
5228 } 5258 }
5229 5259
5230 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) { 5260 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) {
5231 auto it = binding_sets_.find(interface_name); 5261 auto it = binding_sets_.find(interface_name);
5232 if (it != binding_sets_.end()) 5262 if (it != binding_sets_.end())
5233 binding_sets_.erase(it); 5263 binding_sets_.erase(it);
5234 } 5264 }
5235 5265
5236 } // namespace content 5266 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698