Index: content/browser/frame_host/frame_tree.cc |
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc |
index 3e94bbebd176f41e619783a5d6cc56e70dd29286..911ae0decc4bb50fcf5d04dbb6ab668349fbc1b1 100644 |
--- a/content/browser/frame_host/frame_tree.cc |
+++ b/content/browser/frame_host/frame_tree.cc |
@@ -270,15 +270,21 @@ FrameTreeNode* FrameTree::GetFocusedFrame() { |
} |
void FrameTree::SetFocusedFrame(FrameTreeNode* node) { |
- // If the focused frame changed across processes, send a message to the old |
- // focused frame's renderer process to clear focus from that frame and fire |
- // blur events. |
- FrameTreeNode* oldFocusedFrame = GetFocusedFrame(); |
- if (oldFocusedFrame && |
- oldFocusedFrame->current_frame_host()->GetSiteInstance() != |
- node->current_frame_host()->GetSiteInstance()) { |
- DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
- oldFocusedFrame->current_frame_host()->ClearFocus(); |
+ std::set<SiteInstance*> frame_tree_site_instances; |
+ ForEach(base::Bind(&CollectSiteInstances, &frame_tree_site_instances)); |
+ |
+ // Update the focused frame in all other SiteInstances. If focus changes to |
+ // a cross-process frame, this allows the old focused frame's renderer |
+ // process to clear focus from that frame and fire blur events. It also |
+ // ensures that the latest focused frame is available in all renderers to |
+ // compute document.activeElement. |
+ for (const auto& instance : frame_tree_site_instances) { |
alexmos
2015/11/04 21:53:59
The last part of my test illustrates why it's now
Charlie Reis
2015/11/04 22:23:42
Acknowledged.
|
+ if (instance != node->current_frame_host()->GetSiteInstance()) { |
+ DCHECK(SiteIsolationPolicy::AreCrossProcessFramesPossible()); |
+ RenderFrameProxyHost* proxy = |
+ node->render_manager()->GetRenderFrameProxyHost(instance); |
+ proxy->SetFocusedFrame(); |
+ } |
} |
node->set_last_focus_time(base::TimeTicks::Now()); |