From c17cd60630cff9ebc162dcc9ecfec73d11b69bad Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 19 Sep 2014 19:12:44 +0000 Subject: [PATCH] Fix identification of focused frame (issue #1381). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1840 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- libcef/browser/browser_host_impl.cc | 34 ++++++++++----------- libcef/browser/browser_host_impl.h | 9 +++--- libcef/browser/browser_message_filter.cc | 22 ++++++++++++++ libcef/browser/browser_message_filter.h | 1 + libcef/common/cef_messages.h | 8 ----- libcef/renderer/browser_impl.cc | 38 ++---------------------- libcef/renderer/browser_impl.h | 3 -- 7 files changed, 48 insertions(+), 67 deletions(-) diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index e0e6f66e8..f6e77f366 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -2367,6 +2367,23 @@ void CefBrowserHostImpl::DidFailLoad( OnLoadEnd(frame, validated_url, error_code); } +void CefBrowserHostImpl::FrameDetached( + content::RenderFrameHost* render_frame_host) { + base::AutoLock lock_scope(state_lock_); + + const int64 frame_id = render_frame_host->GetRoutingID(); + FrameMap::iterator it = frames_.find(frame_id); + if (it != frames_.end()) { + it->second->Detach(); + frames_.erase(it); + } + + if (main_frame_id_ == frame_id) + main_frame_id_ = CefFrameHostImpl::kInvalidFrameId; + if (focused_frame_id_ == frame_id) + focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId; +} + void CefBrowserHostImpl::PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) { if (client_.get()) { @@ -2385,8 +2402,6 @@ bool CefBrowserHostImpl::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(CefBrowserHostImpl, message) IPC_MESSAGE_HANDLER(CefHostMsg_FrameIdentified, OnFrameIdentified) - IPC_MESSAGE_HANDLER(CefHostMsg_FrameDetached, DetachFrame) - IPC_MESSAGE_HANDLER(CefHostMsg_FrameFocusChange, SetFocusedFrame) IPC_MESSAGE_HANDLER(CefHostMsg_DidFinishLoad, OnDidFinishLoad) IPC_MESSAGE_HANDLER(CefHostMsg_LoadingURLChange, OnLoadingURLChange) IPC_MESSAGE_HANDLER(CefHostMsg_Request, OnRequest) @@ -2692,21 +2707,6 @@ CefRefPtr CefBrowserHostImpl::GetOrCreateFrame( return frame.get(); } -void CefBrowserHostImpl::DetachFrame(int64 frame_id) { - base::AutoLock lock_scope(state_lock_); - - FrameMap::iterator it = frames_.find(frame_id); - if (it != frames_.end()) { - it->second->Detach(); - frames_.erase(it); - } - - if (main_frame_id_ == frame_id) - main_frame_id_ = CefFrameHostImpl::kInvalidFrameId; - if (focused_frame_id_ == frame_id) - focused_frame_id_ = CefFrameHostImpl::kInvalidFrameId; -} - void CefBrowserHostImpl::DetachAllFrames() { FrameMap frames; diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index a92be33ee..64d017b63 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -273,6 +273,9 @@ class CefBrowserHostImpl : public CefBrowserHost, // Handler for URLs involving external protocols. void HandleExternalProtocol(const GURL& url); + // Set the frame that currently has focus. + void SetFocusedFrame(int64 frame_id); + // Thread safe accessors. const CefBrowserSettings& settings() const { return settings_; } CefRefPtr client() const { return client_; } @@ -421,6 +424,8 @@ class CefBrowserHostImpl : public CefBrowserHost, const GURL& validated_url, int error_code, const base::string16& error_description) OVERRIDE; + virtual void FrameDetached( + content::RenderFrameHost* render_frame_host) OVERRIDE; virtual void PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; @@ -482,12 +487,8 @@ class CefBrowserHostImpl : public CefBrowserHost, bool is_main_frame, base::string16 frame_name, const GURL& frame_url); - // Remove the reference to the frame and mark it as detached. - void DetachFrame(int64 frame_id); // Remove the references to all frames and mark them as detached. void DetachAllFrames(); - // Set the frame that currently has focus. - void SetFocusedFrame(int64 frame_id); #if defined(OS_WIN) static LPCTSTR GetWndClass(); diff --git a/libcef/browser/browser_message_filter.cc b/libcef/browser/browser_message_filter.cc index dd4f33097..e82bfd449 100644 --- a/libcef/browser/browser_message_filter.cc +++ b/libcef/browser/browser_message_filter.cc @@ -17,6 +17,7 @@ #include "base/compiler_specific.h" #include "base/bind.h" +#include "content/common/frame_messages.h" #include "content/common/view_messages.h" #include "content/public/browser/render_process_host.h" @@ -37,6 +38,12 @@ void CefBrowserMessageFilter::OnFilterRemoved() { } bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) { + if (message.type() == FrameHostMsg_FrameFocused::ID) { + // Observe but don't handle this message. + OnFrameFocused(message.routing_id()); + return false; + } + bool handled = true; if (message.type() == ViewHostMsg_CreateWindow::ID) { // Observe but don't handle this message. @@ -108,3 +115,18 @@ void CefBrowserMessageFilter::OnCreateWindow( // Reply message is not used. delete reply_msg; } + +void CefBrowserMessageFilter::OnFrameFocused(int32 render_frame_routing_id) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, + base::Bind(&CefBrowserMessageFilter::OnFrameFocused, this, + render_frame_routing_id)); + return; + } + + CefRefPtr browser = + CefBrowserHostImpl::GetBrowserForFrame(host_->GetID(), + render_frame_routing_id); + if (browser) + browser->SetFocusedFrame(render_frame_routing_id); +} diff --git a/libcef/browser/browser_message_filter.h b/libcef/browser/browser_message_filter.h index a5f6d77d2..6e77441d7 100644 --- a/libcef/browser/browser_message_filter.h +++ b/libcef/browser/browser_message_filter.h @@ -41,6 +41,7 @@ class CefBrowserMessageFilter : public IPC::MessageFilter { CefProcessHostMsg_GetNewBrowserInfo_Params* params); void OnCreateWindow(const ViewHostMsg_CreateWindow_Params& params, IPC::Message* reply_msg); + void OnFrameFocused(int32 render_frame_routing_id); content::RenderProcessHost* host_; IPC::Sender* sender_; diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h index 7f032d036..6a3be1812 100644 --- a/libcef/common/cef_messages.h +++ b/libcef/common/cef_messages.h @@ -167,14 +167,6 @@ IPC_MESSAGE_ROUTED3(CefHostMsg_FrameIdentified, int64 /* parent_frame_id */, base::string16 /* frame_name */) -// Sent when a frame has been detached. -IPC_MESSAGE_ROUTED1(CefHostMsg_FrameDetached, - int64 /* frame_id */) - -// Sent when a new frame has been given focus. -IPC_MESSAGE_ROUTED1(CefHostMsg_FrameFocusChange, - int64 /* frame_id */) - // Sent when a frame has finished loading. Based on ViewHostMsg_DidFinishLoad. IPC_MESSAGE_ROUTED4(CefHostMsg_DidFinishLoad, int64 /* frame_id */, diff --git a/libcef/renderer/browser_impl.cc b/libcef/renderer/browser_impl.cc index 035365844..96c181443 100644 --- a/libcef/renderer/browser_impl.cc +++ b/libcef/renderer/browser_impl.cc @@ -273,8 +273,7 @@ CefBrowserImpl::CefBrowserImpl(content::RenderView* render_view, : content::RenderViewObserver(render_view), browser_id_(browser_id), is_popup_(is_popup), - is_windowless_(is_windowless), - last_focused_frame_id_(webkit_glue::kInvalidFrameId) { + is_windowless_(is_windowless) { response_manager_.reset(new CefResponseManager); } @@ -390,7 +389,8 @@ CefRefPtr CefBrowserImpl::GetWebFrameImpl( frames_.insert(std::make_pair(frame_id, framePtr)); int64 parent_id = frame->parent() == NULL ? - webkit_glue::kInvalidFrameId : webkit_glue::GetIdentifier(frame->parent()); + webkit_glue::kInvalidFrameId : + webkit_glue::GetIdentifier(frame->parent()); base::string16 name = frame->uniqueName(); // Notify the browser that the frame has been identified. @@ -529,9 +529,6 @@ void CefBrowserImpl::FrameDetached(WebFrame* frame) { if (it != frame_objects_.end()) frame_objects_.erase(it); } - - // Notify the browser that the frame has detached. - Send(new CefHostMsg_FrameDetached(routing_id(), frame_id)); } void CefBrowserImpl::FocusedNodeChanged(const blink::WebNode& node) { @@ -557,35 +554,6 @@ void CefBrowserImpl::FocusedNodeChanged(const blink::WebNode& node) { } } } - - // TODO(cef): This method is being used as a work-around for identifying frame - // focus changes. The ideal approach would be implementating delegation from - // ChromeClientImpl::focusedFrameChanged(). - - WebFrame* focused_frame = NULL; - - // Try to identify the focused frame from the node. - if (!node.isNull()) { - const blink::WebDocument& document = node.document(); - if (!document.isNull()) - focused_frame = document.frame(); - } - - if (focused_frame == NULL && render_view()->GetWebView()) { - // Try to identify the global focused frame. - focused_frame = render_view()->GetWebView()->focusedFrame(); - } - - int64 frame_id = webkit_glue::kInvalidFrameId; - if (focused_frame != NULL) - frame_id = webkit_glue::GetIdentifier(focused_frame); - - // Don't send a message if the focused frame has not changed. - if (frame_id == last_focused_frame_id_) - return; - - last_focused_frame_id_ = frame_id; - Send(new CefHostMsg_FrameFocusChange(routing_id(), frame_id)); } void CefBrowserImpl::DidCreateDataSource(blink::WebLocalFrame* frame, diff --git a/libcef/renderer/browser_impl.h b/libcef/renderer/browser_impl.h index fd3c26c55..534dd43aa 100644 --- a/libcef/renderer/browser_impl.h +++ b/libcef/renderer/browser_impl.h @@ -141,9 +141,6 @@ class CefBrowserImpl : public CefBrowser, bool is_popup_; bool is_windowless_; - // Id of the last frame that had focus. - int64 last_focused_frame_id_; - // Map of unique frame ids to CefFrameImpl references. typedef std::map > FrameMap; FrameMap frames_;