Fix identification of focused frame (issue #1381).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1840 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2014-09-19 19:12:44 +00:00
parent 3850498939
commit c17cd60630
7 changed files with 48 additions and 67 deletions

View File

@ -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<CefFrame> 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;

View File

@ -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<CefClient> 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();

View File

@ -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<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForFrame(host_->GetID(),
render_frame_routing_id);
if (browser)
browser->SetFocusedFrame(render_frame_routing_id);
}

View File

@ -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_;

View File

@ -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 */,

View File

@ -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<CefFrameImpl> 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,

View File

@ -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<int64, CefRefPtr<CefFrameImpl> > FrameMap;
FrameMap frames_;