Add a CefHandler::HandleSetFocus() callback that gets called when the browser control or a child widget requests focus. This callback gives the client an opportunity to cancel the focus change. (Issue #34, initial patch by tux316).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@29 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2009-06-16 13:52:35 +00:00
parent ff7e8379fb
commit d953faf7f8
8 changed files with 74 additions and 15 deletions

View File

@ -530,6 +530,13 @@ public:
virtual RetVal HandleJSBinding(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Value> object) =0;
// Called when the browser component is requesting focus. |isWidget| will be
// true if the focus is requested for a child widget of the browser window.
// Return RV_CONTINUE to allow the focus to be set or RV_HANDLED to cancel
// setting the focus.
virtual RetVal HandleSetFocus(CefRefPtr<CefBrowser> browser,
bool isWidget) =0;
};

View File

@ -437,6 +437,14 @@ typedef struct _cef_handler_t
enum cef_retval_t (CEF_CALLBACK *handle_jsbinding)(
struct _cef_handler_t* handler, cef_browser_t* browser,
cef_frame_t* frame, struct _cef_v8value_t* object);
// Called when the browser component is requesting focus. |isWidget| will be
// true (1) if the focus is requested for a child widget of the browser
// window. Return RV_CONTINUE to allow the focus to be set or RV_HANDLED to
// cancel setting the focus.
enum cef_retval_t (CEF_CALLBACK *handle_set_focus)(
struct _cef_handler_t* handler, cef_browser_t* browser, int isWidget);
} cef_handler_t;

View File

@ -548,13 +548,19 @@ bool CefBrowserImpl::UIT_Navigate(const BrowserNavigationEntry& entry,
// In case LoadRequest failed before DidCreateDataSource was called.
delegate_->set_pending_extra_data(NULL);
// Restore focus to the main frame prior to loading new request.
// This makes sure that we don't have a focused iframe. Otherwise, that
// iframe would keep focus when the SetFocus called immediately after
// LoadRequest, thus making some tests fail (see http://b/issue?id=845337
// for more details).
GetWebView()->SetFocusedFrame(frame);
UIT_SetFocus(GetWebViewHost(), true);
if (handler_.get() && handler_->HandleSetFocus(this, false) == RV_CONTINUE) {
// Restore focus to the main frame prior to loading new request.
// This makes sure that we don't have a focused iframe. Otherwise, that
// iframe would keep focus when the SetFocus called immediately after
// LoadRequest, thus making some tests fail (see http://b/issue?id=845337
// for more details).
// TODO(cef): The above comment may be wrong, or the below call to
// SetFocusedFrame() may be unnecessary or in the wrong place. See this
// thread for additional details:
// http://groups.google.com/group/chromium-dev/browse_thread/thread/42bcd31b59e3a168
GetWebView()->SetFocusedFrame(frame);
UIT_SetFocus(GetWebViewHost(), true);
}
return true;
}

View File

@ -548,8 +548,11 @@ void BrowserWebViewDelegate::DidScrollRect(WebWidget* webwidget, int dx, int dy,
}
void BrowserWebViewDelegate::Focus(WebWidget* webwidget) {
if (WebWidgetHost* host = GetHostForWidget(webwidget))
browser_->UIT_SetFocus(host, true);
if (WebWidgetHost* host = GetHostForWidget(webwidget)) {
CefRefPtr<CefHandler> handler = browser_->GetHandler();
if (handler.get() && handler->HandleSetFocus(browser_, true) == RV_CONTINUE)
browser_->UIT_SetFocus(host, true);
}
}
void BrowserWebViewDelegate::Blur(WebWidget* webwidget) {

View File

@ -440,6 +440,18 @@ enum cef_retval_t CEF_CALLBACK handler_handle_jsbinding(
CefV8ValueCToCpp::Wrap(object));
}
enum cef_retval_t CEF_CALLBACK handler_handle_set_focus(
struct _cef_handler_t* handler, cef_browser_t* browser, int isWidget)
{
DCHECK(handler);
DCHECK(browser);
if(!handler || !browser)
return RV_CONTINUE;
return CefHandlerCppToC::Get(handler)->HandleSetFocus(
CefBrowserCToCpp::Wrap(browser), isWidget);
}
CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls)
: CefCppToC<CefHandlerCppToC, CefHandler, cef_handler_t>(cls)
@ -466,6 +478,7 @@ CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls)
handler_handle_before_window_close;
struct_.struct_.handle_take_focus = handler_handle_take_focus;
struct_.struct_.handle_jsbinding = handler_handle_jsbinding;
struct_.struct_.handle_set_focus = handler_handle_set_focus;
}
#ifdef _DEBUG

View File

@ -328,6 +328,16 @@ CefHandler::RetVal CefHandlerCToCpp::HandleJSBinding(
CefFrameCppToC::Wrap(frame), CefV8ValueCppToC::Wrap(object));
}
CefHandler::RetVal CefHandlerCToCpp::HandleSetFocus(
CefRefPtr<CefBrowser> browser, bool isWidget)
{
if(CEF_MEMBER_MISSING(struct_, handle_set_focus))
return RV_CONTINUE;
return struct_->handle_set_focus(struct_, CefBrowserCppToC::Wrap(browser),
isWidget);
}
#ifdef _DEBUG
long CefCToCpp<CefHandlerCToCpp, CefHandler, cef_handler_t>::DebugObjCt = 0;
#endif

View File

@ -90,6 +90,8 @@ public:
virtual RetVal HandleJSBinding(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Value> object);
virtual RetVal HandleSetFocus(CefRefPtr<CefBrowser> browser,
bool isWidget);
};

View File

@ -720,6 +720,16 @@ public:
return RV_HANDLED;
}
// Called when the browser component is requesting focus. |isWidget| will be
// true if the focus is requested for a child widget of the browser window.
// Return RV_CONTINUE to allow the focus to be set or RV_HANDLED to cancel
// setting the focus.
virtual RetVal HandleSetFocus(CefRefPtr<CefBrowser> browser,
bool isWidget)
{
return RV_CONTINUE;
}
// Retrieve the current navigation state flags
void GetNavState(bool &isLoading, bool &canGoBack, bool &canGoForward)
{