| 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 4fda786ed2d3d8815db9bbc196959b3af504d513..02a3fc885c17b9f4832345096fbbd66e88374079 100644
|
| --- a/content/browser/web_contents/web_contents_impl.cc
|
| +++ b/content/browser/web_contents/web_contents_impl.cc
|
| @@ -330,8 +330,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.
|
| @@ -340,7 +340,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.
|
| @@ -354,16 +354,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)
|
| @@ -435,6 +447,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.
|
| @@ -1799,7 +1817,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;
|
|
|
| @@ -4135,6 +4154,35 @@ 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_)
|
| + 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
|
| @@ -4542,6 +4590,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,
|
| @@ -4919,17 +4988,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();
|
| }
|
| @@ -4987,19 +5045,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
|
|
|