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

Unified Diff: content/browser/web_contents/web_contents_impl.cc

Issue 2451143003: <webview>: Correctly shift focus between WebContents. (Closed)
Patch Set: Address comments from alexmos and lfg. Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
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 ae0a6ecea2d81617526e2ec85bd4aa8e25c63d73..71f83fbf5f31293b7e9fca0342c583d78d61e7e5 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1847,6 +1847,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.
@@ -4626,6 +4630,49 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {
}
}
+void WebContentsImpl::ChangeFocusIfNecessary() {
+ // Only change focus if we are not currently focused.
+ WebContentsImpl* old_contents = GetFocusedWebContents();
+ if (old_contents == this)
+ return;
+
+ // Ensure that the embedding frame in each outer WebContent's frame tree is
+ // focused, if present.
+ WebContentsImpl* web_contents = this;
+ while (web_contents->GetOuterWebContents()) {
+ FrameTreeNode* tree_node = FrameTreeNode::GloballyFindByID(
+ web_contents->GetOuterDelegateFrameTreeNodeId());
+ RenderFrameProxyHost* outer_proxy = web_contents->frame_tree_.root()
+ ->render_manager()
+ ->GetProxyToOuterDelegate();
+ // In BrowserPlugin, we don't have a node in the embedder, we are implicitly
+ // embedded in the main frame.
+ // TODO(http://crbug.com/533069): Delete once BrowserPlugin is gone.
+ if (!tree_node) {
+ tree_node = web_contents->GetOuterWebContents()
+ ->GetMainFrame()
+ ->frame_tree_node();
+ }
+
+ web_contents = web_contents->GetOuterWebContents();
alexmos 2016/10/31 18:57:57 nit: seems like you could move this up to just bef
avallee 2016/11/07 19:18:44 Loop deleted. I think this will not be necessary.
+ if (tree_node == web_contents->frame_tree_.GetFocusedFrame())
+ break;
+ if (tree_node)
+ web_contents->frame_tree_.SetFocusedFrame(tree_node,
+ outer_proxy->GetSiteInstance());
+
+ if (outer_proxy)
+ outer_proxy->SetFocusedFrame();
alexmos 2016/10/31 18:57:57 Does this need to be done if the tree_node is alre
avallee 2016/11/07 19:18:44 I'm not sure, but deleted for now, it seems notify
+ }
+
+ // 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_) {
@@ -4633,22 +4680,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);
- }
+ ChangeFocusIfNecessary();
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::AddMessageToConsole(int32_t level,
@@ -4678,6 +4712,20 @@ void WebContentsImpl::OnUserInteraction(
rdh->OnUserGesture();
}
+void WebContentsImpl::EnsureOwningContentsIsFocused(
+ RenderWidgetHostImpl* render_widget_host) {
+ if (!GuestMode::IsCrossProcessFrameGuest(this) && browser_plugin_guest_)
alexmos 2016/10/31 18:57:57 Can you please explain this check? So if this is
avallee 2016/11/07 19:18:44 This fixes an issue with TextInputState. This is t
EhsanK 2016/11/08 16:05:47 This is actually for making sure PDF runs on Brows
alexmos 2016/11/09 02:47:54 I think the intent of the early return in WebConte
EhsanK 2016/11/09 16:58:02 alexmos@: If I understand your question, we are as
alexmos 2016/11/09 18:16:57 Right.
EhsanK 2016/11/09 19:17:15 No, actually this is using --use-cpffg. BTW, the n
alexmos 2016/11/10 18:35:44 Thanks for clarifying. What worried me is that if
EhsanK 2016/11/10 19:04:56 You are right and comparing with the old code we a
alexmos 2016/11/10 19:16:55 Coming back to this CL, I think this check is fine
avallee 2016/11/16 05:38:09 I tested http://foersom.com/net/HowTo/data/OoPdfFo
alexmos 2016/11/16 23:29:03 Acknowledged.
+ return;
+
+ RenderWidgetHostImpl* focused_widget =
+ GetFocusedRenderWidgetHost(render_widget_host);
+
+ if (focused_widget != render_widget_host &&
+ focused_widget->delegate() != render_widget_host->delegate()) {
+ ChangeFocusIfNecessary();
+ }
+}
+
void WebContentsImpl::OnIgnoredUIEvent() {
// Notify observers.
for (auto& observer : observers_)

Powered by Google App Engine
This is Rietveld 408576698