cefsimple: browser doesn't receive input focus on launch
Closed this issue · 5 comments
Describe the bug
I am trying to modify cefsimple example and set focus on the browser when the app is first launched. I found out that it does not work, unless I explicitly click somewhere in the browser.
To Reproduce
Steps to reproduce the behavior:
- Implement OnPreKeyEvent. In my case, I was trying to prevent accelerators keys. Example (you can add a cout here, and you will see it is never triggered at app first launch, meaning that the browser did not receive focus):
bool SimpleHandler::OnPreKeyEvent(CefRefPtr browser,
const CefKeyEvent& event,
CefEventHandle os_event,
bool* is_keyboard_shortcut) {
if (event.type != KEYEVENT_RAWKEYDOWN &&
event.type != KEYEVENT_KEYDOWN)
return false;
// Check for modifiers
bool ctrl = (event.modifiers & EVENTFLAG_CONTROL_DOWN) != 0;
bool shift = (event.modifiers & EVENTFLAG_SHIFT_DOWN) != 0;
bool cmd = (event.modifiers & EVENTFLAG_COMMAND_DOWN) != 0; // For macOS
//bool alt = (event.modifiers & EVENTFLAG_ALT_DOWN) != 0;
// Helper lambda to check for ctrl on Windows/Linux or cmd on macOS
auto ctrlOrCmd = [ctrl, cmd]() {
#if defined(OS_MAC)
return cmd;
#else
return ctrl;
#endif
};
// Block F1, F7, F12 (DevTools)
if (event.native_key_code == 0xffc9 || // Linux F12
event.windows_key_code == VK_F12 || // Windows F12
event.native_key_code == 0x7B || // macOS F12
event.native_key_code == 0xffbe || // Linux F1
event.windows_key_code == VK_F1 || // Windows F1
event.native_key_code == 0x7A || // macOS F1
event.native_key_code == 0xffc4 || // Linux F7
event.windows_key_code == VK_F7 || // Windows F7
event.native_key_code == 0x76) { // macOS F7
return true;
}
// Block any combination where Ctrl or Cmd is pressed
if (ctrlOrCmd()) {
return true;
}
return false;
}
- Set focus wherever appropriate, to window, browser_view, and browser.
Example: in SimpleWindowDelegate, browser_view_->RequestFocus();
Implement OnBeforeResourceLoad with browser->GetHost()->SetFocus(true);
Implement OnLoadEnd with browser->GetHost()->SetFocus(true);
Implement delayed focus to the browser in OnWindowCreated;
Implement CefFocusHandler and OnFocusedNodeChanged (it won't get fired at app first launch).
- Launch the app and press F12, or CTRL+P, etc. If the focus was set, it should have no effect, but instead the accelerator keys still work, until one clicks somewhere inside the browser; then, the browser component correctly receive focus and the app behaves as expected.
Expected behavior
Cefbrowser should receive focus at app startup.
Versions (please complete the following information):
- OS: Arch Linux, latest update
- CEF Version: 130.1.9+gfc42567+chromium-130.0.6723.70
Additional context
I only tested cefsimple with the url "https://www.google.com".
I cannot reproduce on Google Chrome, because it's not possible to determine which component is having focus at first launch.
I also noticed that, once the browser receives focus, OnFocusedNodeChanged correctly triggers when I click inside the browser. But When I click outside the app, OnTakeFocus never fires up. Also, CefWindow's RemoveAllAccelerators does nothing, always in respect to app's startup. So it must be some general issue with focus.
The BrowserView should receive focus when the cefsimple app is launched due to the RequestFocus call. For example, when loading google.com you should see a blinking cursor on the search field.
When I click outside the app, OnTakeFocus never fires up
This may only be called when focus moves to a different element in the same window, not when the window itself loses focus.
CefWindow's RemoveAllAccelerators does nothing
This may not remove accelerators registered internally by Chrome.
For example, when loading google.com you should see a blinking cursor on the search field.
This doesn't work with cefsimple or cefclient on Windows or macOS either (tested M131). The window does have focus as indicated by pressing the TAB key to move between different elements. With cefclient the address bar gets focus first when pressing the TAB key.
With Google Chrome (launching with the URL in the shortcut on Windows) the search field gets initial focus as expected.
This doesn't work with cefsimple or cefclient on Windows or macOS either (tested M131).
This works as expected with --use-alloy-style
It looks like the call to RequestFocus
in OnWindowCreated is a no-op. With Alloy style initial focus is assigned via:
* thread #1, name = 'CrBrowserMain', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x00000003d4f0a9c0 Chromium Embedded Framework`views::FocusManager::SetFocusedViewWithReason(this=0x0000010401fec1c0, view=0x0000010400186800, reason=kDirectFocusChange) at focus_manager.cc:296:3
frame #1: 0x00000003d4f0ba58 Chromium Embedded Framework`views::FocusManager::SetFocusedView(this=0x0000010401fec1c0, view=0x0000010400186800) at focus_manager.cc:354:3
frame #2: 0x00000003d4fbee9c Chromium Embedded Framework`views::View::RequestFocus(this=0x0000010400186800) at view.cc:1986:22
frame #3: 0x00000003b72213b4 Chromium Embedded Framework`CefBrowserPlatformDelegateViews::SetFocus(this=0x0000010401a5dbc0, setFocus=true) at browser_platform_delegate_views.cc:165:33
frame #4: 0x00000003b6f426f0 Chromium Embedded Framework`AlloyBrowserHostImpl::OnSetFocus(this=0x00000104002ad200, source=FOCUS_SOURCE_NAVIGATION) at alloy_browser_host_impl.cc:650:25
frame #5: 0x00000003b6fa1390 Chromium Embedded Framework`CefBrowserHostBase::LoadMainFrameURL(this=0x00000104002ad200, params=0x000000016fdfbfb8) at browser_host_base.cc:1234:5
frame #6: 0x00000003b6f3e8a4 Chromium Embedded Framework`AlloyBrowserHostImpl::Create(create_params=0x0000010400177c80) at alloy_browser_host_impl.cc:149:14
Part of the problem is that View::RequestFocus calls IsFocusable, which returns false because View::GetFocusBehavior returns FocusBehavior::NEVER (the View in this case is a ChromeBrowserView). This is the default value for View::focus_behavior_
. We need to explicitly give focus to the child views::WebView instead.