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

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

Issue 2451143003: <webview>: Correctly shift focus between WebContents. (Closed)
Patch Set: Fix creis comments. 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
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
4676 // The PDF plugin still runs as a BrowserPlugin and must go through the
4677 // input redirection mechanism. It must not become focused direcly.
4647 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { 4678 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) {
4648 frame_tree_.SetFocusedFrame(node, source); 4679 frame_tree_.SetFocusedFrame(node, source);
4649 return; 4680 return;
4650 } 4681 }
4651 4682
4652 // 1. Find old focused frame and unfocus it. 4683 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 4684
4662 frame_tree_.SetFocusedFrame(node, source); 4685 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 } 4686 }
4669 4687
4670 bool WebContentsImpl::DidAddMessageToConsole(int32_t level, 4688 bool WebContentsImpl::DidAddMessageToConsole(int32_t level,
4671 const base::string16& message, 4689 const base::string16& message,
4672 int32_t line_no, 4690 int32_t line_no,
4673 const base::string16& source_id) { 4691 const base::string16& source_id) {
4674 if (!delegate_) 4692 if (!delegate_)
4675 return false; 4693 return false;
4676 return delegate_->DidAddMessageToConsole(this, level, message, line_no, 4694 return delegate_->DidAddMessageToConsole(this, level, message, line_no,
4677 source_id); 4695 source_id);
4678 } 4696 }
4679 4697
4680 void WebContentsImpl::OnUserInteraction( 4698 void WebContentsImpl::OnUserInteraction(
4681 RenderWidgetHostImpl* render_widget_host, 4699 RenderWidgetHostImpl* render_widget_host,
4682 const blink::WebInputEvent::Type type) { 4700 const blink::WebInputEvent::Type type) {
4683 // Ignore unless the widget is currently in the frame tree. 4701 // Ignore unless the widget is currently in the frame tree.
4684 if (!HasMatchingWidgetHost(&frame_tree_, render_widget_host)) 4702 if (!HasMatchingWidgetHost(&frame_tree_, render_widget_host))
4685 return; 4703 return;
4686 4704
4687 for (auto& observer : observers_) 4705 for (auto& observer : observers_)
4688 observer.DidGetUserInteraction(type); 4706 observer.DidGetUserInteraction(type);
4689 4707
4690 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); 4708 ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get();
4691 // Exclude scroll events as user gestures for resource load dispatches. 4709 // Exclude scroll events as user gestures for resource load dispatches.
4692 // rdh is NULL in unittests. 4710 // rdh is NULL in unittests.
4693 if (rdh && type != blink::WebInputEvent::MouseWheel) 4711 if (rdh && type != blink::WebInputEvent::MouseWheel)
4694 rdh->OnUserGesture(); 4712 rdh->OnUserGesture();
4695 } 4713 }
4696 4714
4715 void WebContentsImpl::FocusOwningWebContents(
4716 RenderWidgetHostImpl* render_widget_host) {
4717 // The PDF plugin still runs as a BrowserPlugin and must go through the
4718 // input redirection mechanism. It must not become focused direcly.
4719 if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_)
4720 return;
4721
4722 RenderWidgetHostImpl* focused_widget =
4723 GetFocusedRenderWidgetHost(render_widget_host);
4724
4725 if (focused_widget != render_widget_host &&
4726 focused_widget->delegate() != render_widget_host->delegate()) {
4727 SetAsFocusedWebContentsIfNecessary();
4728 }
4729 }
4730
4697 void WebContentsImpl::OnIgnoredUIEvent() { 4731 void WebContentsImpl::OnIgnoredUIEvent() {
4698 // Notify observers. 4732 // Notify observers.
4699 for (auto& observer : observers_) 4733 for (auto& observer : observers_)
4700 observer.DidGetIgnoredUIEvent(); 4734 observer.DidGetIgnoredUIEvent();
4701 } 4735 }
4702 4736
4703 void WebContentsImpl::RendererUnresponsive( 4737 void WebContentsImpl::RendererUnresponsive(
4704 RenderWidgetHostImpl* render_widget_host, 4738 RenderWidgetHostImpl* render_widget_host,
4705 RendererUnresponsiveType type) { 4739 RendererUnresponsiveType type) {
4706 for (auto& observer : observers_) 4740 for (auto& observer : observers_)
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
5227 dialog_manager_ = dialog_manager; 5261 dialog_manager_ = dialog_manager;
5228 } 5262 }
5229 5263
5230 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) { 5264 void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) {
5231 auto it = binding_sets_.find(interface_name); 5265 auto it = binding_sets_.find(interface_name);
5232 if (it != binding_sets_.end()) 5266 if (it != binding_sets_.end())
5233 binding_sets_.erase(it); 5267 binding_sets_.erase(it);
5234 } 5268 }
5235 5269
5236 } // namespace content 5270 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698