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

Unified 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: Added test and addressed comments. Created 4 years, 6 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 bb4128c8f0fda709aef73e59c5b2819c0d1bd7d6..2d2e054e3594ccaf88e364a399f4d0e31aed8fdf 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -331,8 +331,8 @@ WebContentsImpl::ColorChooserInfo::~ColorChooserInfo() {
WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode()
: outer_web_contents_(nullptr),
outer_contents_frame_tree_node_id_(
- FrameTreeNode::kFrameTreeNodeInvalidId) {
-}
+ FrameTreeNode::kFrameTreeNodeInvalidId),
+ focused_web_contents_(nullptr) {}
WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
alexmos 2016/06/07 22:03:43 What will happen if the currently focused WebConte
avallee 2016/06/15 13:32:10 It feels like there should be no element with focu
alexmos 2016/06/24 01:38:49 Acknowledged.
// Remove child pointer from our parent.
@@ -341,7 +341,7 @@ WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
outer_web_contents_->node_->inner_web_contents_tree_nodes_;
ChildrenSet::iterator iter = child_ptrs_in_parent.find(this);
DCHECK(iter != child_ptrs_in_parent.end());
- child_ptrs_in_parent.erase(this);
+ child_ptrs_in_parent.erase(iter);
}
// Remove parent pointers from our children.
@@ -355,16 +355,30 @@ WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() {
void WebContentsImpl::WebContentsTreeNode::ConnectToOuterWebContents(
WebContentsImpl* outer_web_contents,
RenderFrameHostImpl* outer_contents_frame) {
+ DCHECK(!focused_web_contents_) << "Should not attach a root node.";
outer_web_contents_ = outer_web_contents;
outer_contents_frame_tree_node_id_ =
outer_contents_frame->frame_tree_node()->frame_tree_node_id();
- if (!outer_web_contents_->node_)
+ if (!outer_web_contents_->node_) {
+ // This will reached when connecting into a new WebContents tree. We
alexmos 2016/06/07 22:03:43 s/will reached/will only be reached/
avallee 2016/06/15 13:32:10 Done.
+ // implicitly set the root of this tree as being focused since this is
alexmos 2016/06/07 22:03:43 The part after "since" was difficult to parse ("ca
avallee 2016/06/15 13:32:10 Done.
+ // called in the process of creating an inner WebContents so I couldn't be
+ // focused yet.
outer_web_contents_->node_.reset(new WebContentsTreeNode());
+ outer_web_contents_->node_->SetFocusedWebContents(outer_web_contents_);
+ }
outer_web_contents_->node_->inner_web_contents_tree_nodes_.insert(this);
}
+void WebContentsImpl::WebContentsTreeNode::SetFocusedWebContents(
+ WebContentsImpl* web_contents) {
+ DCHECK(!outer_web_contents())
+ << "Only the outermost WebContents tracks focus.";
+ focused_web_contents_ = web_contents;
+}
+
// WebContentsImpl -------------------------------------------------------------
WebContentsImpl::WebContentsImpl(BrowserContext* browser_context)
@@ -1789,7 +1803,8 @@ RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost(
if (receiving_widget != GetMainFrame()->GetRenderWidgetHost())
return receiving_widget;
- FrameTreeNode* focused_frame = frame_tree_.GetFocusedFrame();
+ FrameTreeNode* focused_frame =
+ GetFocusedWebContents()->frame_tree_.GetFocusedFrame();
if (!focused_frame)
return receiving_widget;
@@ -4087,6 +4102,36 @@ void WebContentsImpl::RemoveBrowserPluginEmbedder() {
browser_plugin_embedder_.reset();
}
+WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
+ if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
+ if (node_)
+ return node_->outer_web_contents();
+ } else {
+ if (GetBrowserPluginGuest())
+ return GetBrowserPluginGuest()->embedder_web_contents();
+ }
+ return nullptr;
+}
+
+WebContentsImpl* WebContentsImpl::GetFocusedWebContents() {
+ // There is no inner web contents.
+ if (!node_) {
+ return this;
+ }
+
+ // If we've found root by iterating through outer WebContents, root must have
+ // a valid node_ since the inner WebContents will have created one when
+ // connecting.
+ return GetOutermostWebContents()->node_->focused_web_contents();
+}
+
+WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
+ WebContentsImpl* root = this;
+ while (root->GetOuterWebContents())
+ root = root->GetOuterWebContents();
+ return root;
+}
+
void WebContentsImpl::RenderViewCreated(RenderViewHost* render_view_host) {
// Don't send notifications if we are just creating a swapped-out RVH for
// the opener chain. These won't be used for view-source or WebUI, so it's
@@ -4485,6 +4530,27 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {
}
}
+void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
+ SiteInstance* source) {
+ // 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);
+ }
+
+ 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 &&
+ BrowserPluginGuestMode::UseCrossProcessFramesForGuests())
+ rwh->Focus();
+}
+
bool WebContentsImpl::AddMessageToConsole(int32_t level,
const base::string16& message,
int32_t line_no,
@@ -4862,17 +4928,6 @@ RenderFrameHostManager* WebContentsImpl::GetRenderManager() const {
return frame_tree_.root()->render_manager();
}
-WebContentsImpl* WebContentsImpl::GetOuterWebContents() {
- if (BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
- if (node_)
- return node_->outer_web_contents();
- } else {
- if (GetBrowserPluginGuest())
- return GetBrowserPluginGuest()->embedder_web_contents();
- }
- return nullptr;
-}
-
BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const {
return browser_plugin_guest_.get();
}

Powered by Google App Engine
This is Rietveld 408576698