Chromium Code Reviews| Index: content/browser/web_contents/web_contents_impl.cc |
| diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc |
| index b3b4e822ba2b0739870141f28e0dc31c20681428..7375bbd50da4ea1d532be0a7ca594a60c656ad09 100644 |
| --- a/content/browser/web_contents/web_contents_impl.cc |
| +++ b/content/browser/web_contents/web_contents_impl.cc |
| @@ -482,9 +482,9 @@ WebContentsImpl::~WebContentsImpl() { |
| entry.second->CloseAllBindings(); |
| WebContentsImpl* outermost = GetOutermostWebContents(); |
| - if (GetFocusedWebContents() == this && this != outermost) { |
| + if (this != outermost && ContainsOrIsFocusedWebContents()) { |
| // If the current WebContents is in focus, unset it. |
| - outermost->node_->SetFocusedWebContents(outermost); |
| + outermost->SetAsFocusedWebContentsIfNecessary(); |
| } |
| for (FrameTreeNode* node : frame_tree_.Nodes()) { |
| @@ -1870,6 +1870,10 @@ RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( |
| return RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); |
| } |
| +RenderWidgetHostImpl* WebContentsImpl::GetRenderWidgetHostWithPageFocus() { |
| + return GetFocusedWebContents()->GetMainFrame()->GetRenderWidgetHost(); |
| +} |
| + |
| void WebContentsImpl::EnterFullscreenMode(const GURL& origin) { |
| // This method is being called to enter renderer-initiated fullscreen mode. |
| // Make sure any existing fullscreen widget is shut down first. |
| @@ -4223,6 +4227,17 @@ WebContentsImpl* WebContentsImpl::GetFocusedWebContents() { |
| return outermost->node_->focused_web_contents(); |
| } |
| +bool WebContentsImpl::ContainsOrIsFocusedWebContents() { |
| + for (WebContentsImpl* focused_contents = GetFocusedWebContents(); |
| + focused_contents; |
| + focused_contents = focused_contents->GetOuterWebContents()) { |
| + if (focused_contents == this) |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { |
| WebContentsImpl* root = this; |
| while (root->GetOuterWebContents()) |
| @@ -4642,6 +4657,20 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) { |
| } |
| } |
| +void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() { |
| + // Only change focus if we are not currently focused. |
| + WebContentsImpl* old_contents = GetFocusedWebContents(); |
| + if (old_contents == this) |
| + return; |
| + |
| + // Send a page level blur to the old contents so that it displays inactive UI |
| + // and focus this contents to activate it. |
| + if (old_contents) |
| + old_contents->GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(false); |
| + GetMainFrame()->GetRenderWidgetHost()->SetPageFocus(true); |
| + GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| +} |
| + |
| void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| SiteInstance* source) { |
| if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_) { |
| @@ -4649,22 +4678,9 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, |
| return; |
| } |
| - // 1. Find old focused frame and unfocus it. |
| - // 2. Focus the new frame in the current FrameTree. |
| - // 3. Set current WebContents as focused. |
| - WebContentsImpl* old_focused_contents = GetFocusedWebContents(); |
| - if (old_focused_contents != this) { |
| - // Focus is moving between frame trees, unfocus the frame in the old tree. |
| - old_focused_contents->frame_tree_.SetFocusedFrame(nullptr, source); |
| - GetOutermostWebContents()->node_->SetFocusedWebContents(this); |
| - } |
| + SetAsFocusedWebContentsIfNecessary(); |
| frame_tree_.SetFocusedFrame(node, source); |
| - |
| - // TODO(avallee): Remove this once page focus is fixed. |
| - RenderWidgetHostImpl* rwh = node->current_frame_host()->GetRenderWidgetHost(); |
| - if (rwh && old_focused_contents != this) |
| - rwh->Focus(); |
| } |
| bool WebContentsImpl::DidAddMessageToConsole(int32_t level, |
| @@ -4694,6 +4710,20 @@ void WebContentsImpl::OnUserInteraction( |
| rdh->OnUserGesture(); |
| } |
| +void WebContentsImpl::EnsureOwningContentsIsFocused( |
| + RenderWidgetHostImpl* render_widget_host) { |
| + 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.
|
| + return; |
| + |
| + RenderWidgetHostImpl* focused_widget = |
| + GetFocusedRenderWidgetHost(render_widget_host); |
| + |
| + if (focused_widget != render_widget_host && |
| + focused_widget->delegate() != render_widget_host->delegate()) { |
| + SetAsFocusedWebContentsIfNecessary(); |
| + } |
| +} |
| + |
| void WebContentsImpl::OnIgnoredUIEvent() { |
| // Notify observers. |
| for (auto& observer : observers_) |