diff --git a/libcef/browser_impl.cc b/libcef/browser_impl.cc index 5112e5a83..90f5878a3 100644 --- a/libcef/browser_impl.cc +++ b/libcef/browser_impl.cc @@ -169,6 +169,7 @@ CefBrowserImpl::CefBrowserImpl(const CefWindowInfo& windowInfo, can_go_forward_(false), has_document_(false), is_dropping_(false), + is_in_onsetfocus_(false), unique_id_(0) #if defined(OS_WIN) , opener_was_disabled_by_modal_loop_(false), @@ -229,6 +230,26 @@ void CefBrowserImpl::StopLoad() { void CefBrowserImpl::SetFocus(bool enable) { if (CefThread::CurrentlyOn(CefThread::UI)) { + // If SetFocus() is called from inside the OnSetFocus() callback do not re- + // enter the callback. + if (enable && !is_in_onsetfocus_) { + WebViewHost* host = UIT_GetWebViewHost(); + if (host) { + CefRefPtr client = GetClient(); + if (client.get()) { + CefRefPtr handler = client->GetFocusHandler(); + if (handler.get()) { + is_in_onsetfocus_ = true; + bool handled = handler->OnSetFocus(this, FOCUS_SOURCE_SYSTEM); + is_in_onsetfocus_ = false; + + if (handled) + return; + } + } + } + } + UIT_SetFocus(UIT_GetWebViewHost(), enable); } else { CefThread::PostTask(CefThread::UI, FROM_HERE, @@ -1003,7 +1024,6 @@ bool CefBrowserImpl::UIT_Navigate(const BrowserNavigationEntry& entry, return true; } - void CefBrowserImpl::UIT_SetSize(PaintElementType type, int width, int height) { if (type == PET_VIEW) { WebViewHost* host = UIT_GetWebViewHost(); diff --git a/libcef/browser_impl.h b/libcef/browser_impl.h index 375effb0f..3004c3562 100644 --- a/libcef/browser_impl.h +++ b/libcef/browser_impl.h @@ -399,6 +399,10 @@ class CefBrowserImpl : public CefBrowser { // True if a drop action is occuring. bool is_dropping_; + // True if currently in the OnSetFocus callback. Only accessed on the UI + // thread. + bool is_in_onsetfocus_; + #if defined(OS_WIN) // Context object used to manage printing. printing::PrintingContext print_context_; diff --git a/libcef/browser_impl_win.cc b/libcef/browser_impl_win.cc index e7c54d57d..909e0c35b 100644 --- a/libcef/browser_impl_win.cc +++ b/libcef/browser_impl_win.cc @@ -104,21 +104,8 @@ LRESULT CALLBACK CefBrowserImpl::WndProc(HWND hwnd, UINT message, return 0; case WM_SETFOCUS: - if (browser) { - WebViewHost* host = browser->UIT_GetWebViewHost(); - if (host) { - bool handled = false; - CefRefPtr client = browser->GetClient(); - if (client.get()) { - CefRefPtr handler = client->GetFocusHandler(); - if (handler.get()) - handled = handler->OnSetFocus(browser, FOCUS_SOURCE_SYSTEM); - } - - if (!handled) - browser->UIT_SetFocus(host, true); - } - } + if (browser) + browser->SetFocus(true); return 0; case WM_ERASEBKGND: diff --git a/libcef/webwidget_host_win.cc b/libcef/webwidget_host_win.cc index 9a91acdc6..89fc8c6d4 100644 --- a/libcef/webwidget_host_win.cc +++ b/libcef/webwidget_host_win.cc @@ -7,6 +7,7 @@ #include #include "libcef/webwidget_host.h" +#include "libcef/browser_impl.h" #include "libcef/cef_thread.h" #include "base/bind.h" @@ -599,11 +600,19 @@ void WebWidgetHost::MouseEvent(UINT message, WPARAM wparam, LPARAM lparam) { case WebInputEvent::MouseDown: if (!popup()) { SetCapture(view_); - // This mimics a temporary workaround in RenderWidgetHostViewWin - // for bug 765011 to get focus when the mouse is clicked. This - // happens after the mouse down event is sent to the renderer - // because normally Windows does a WM_SETFOCUS after WM_LBUTTONDOWN. - ::SetFocus(view_); + + HWND parent_hwnd = ::GetParent(view_); + if (parent_hwnd) { + CefRefPtr browser = + static_cast(ui::GetWindowUserData(parent_hwnd)); + if (browser.get()) { + // This mimics a temporary workaround in RenderWidgetHostViewWin + // for bug 765011 to get focus when the mouse is clicked. This + // happens after the mouse down event is sent to the renderer + // because normally Windows does a WM_SETFOCUS after WM_LBUTTONDOWN. + browser->SetFocus(true); + } + } } break; case WebInputEvent::MouseUp: