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

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: Address nasko@ comments. Created 4 years, 5 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 1fb9201c58d29fbde43c47ce8305b46c99893df0..7e7b524ff1027ff1fc97585cffa148168d0b4291 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -337,8 +337,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() {
// Remove child pointer from our parent.
@@ -347,7 +347,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.
@@ -361,16 +361,28 @@ 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 only be reached when creating a new WebContents tree.
+ // Initialize the root of this tree and set it as focused.
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)
@@ -446,6 +458,12 @@ WebContentsImpl::~WebContentsImpl() {
rwh_input_event_router_.reset();
+ WebContentsImpl* outermost = GetOutermostWebContents();
+ if (GetFocusedWebContents() == this && this != outermost) {
+ // If the current WebContents is in focus, unset it.
+ outermost->node_->SetFocusedWebContents(outermost);
+ }
+
for (FrameTreeNode* node : frame_tree_.Nodes()) {
// Delete all RFHs pending shutdown, which will lead the corresponding RVHs
// to be shutdown and be deleted as well.
@@ -1810,7 +1828,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;
@@ -4175,6 +4194,39 @@ 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 or outer web contents.
+ if (!node_ && !GetBrowserPluginGuest())
+ return this;
+
+ // We may need to create a node_ on the outermost contents in the
+ // BrowserPlugin case.
+ WebContentsImpl* outermost = GetOutermostWebContents();
+ if (!outermost->node_) {
+ outermost->node_.reset(new WebContentsTreeNode());
+ outermost->node_->SetFocusedWebContents(outermost);
+ }
+ return outermost->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
@@ -4577,6 +4629,32 @@ void WebContentsImpl::EnsureOpenerProxiesExist(RenderFrameHost* source_rfh) {
}
}
+void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node,
+ SiteInstance* source) {
+ if (!BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
+ frame_tree_.SetFocusedFrame(node, source);
+ 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);
+ }
+
+ 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,
@@ -4960,17 +5038,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();
}
@@ -5028,19 +5095,6 @@ WebUI* WebContentsImpl::CreateWebUI(const GURL& url,
return NULL;
}
-// TODO(paulmeyer): This method will not be used until find-in-page across
-// GuestViews is implemented.
-WebContentsImpl* WebContentsImpl::GetOutermostWebContents() {
- // Find the outer-most WebContents.
- WebContentsImpl* outermost_web_contents = this;
- while (outermost_web_contents->node_ &&
- outermost_web_contents->node_->outer_web_contents()) {
- outermost_web_contents =
- outermost_web_contents->node_->outer_web_contents();
- }
- return outermost_web_contents;
-}
-
FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() {
// TODO(paulmeyer): This method will need to access (or potentially create)
// the FindRequestManager in the outermost WebContents once find-in-page
« no previous file with comments | « content/browser/web_contents/web_contents_impl.h ('k') | content/browser/web_contents/web_contents_view_child_frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698