views: Fix Chrome style browser RequestFocus behavior (fixes #3819)

Fix implementation of CefBrowserView::RequestFocus for Chrome style
browsers. Match Alloy style behavior of requesting browser focus
(calling OnSetFocus) after initial navigation. Add CefView::HasFocus
and CefWindow::GetFocusedView that can be used in combination with
CefWindow::IsActive to determine global keyboard focus.

Update sample applications for the new behavior.

In cefclient:
- Browser receives initial focus via ViewsWindow::RequestBrowserFocus.
- When running with `--show-overlay-browser` (see #3790):
  - Give initial focus to the overlay browser.
  - Change the overlay popout shortcut to CTRL+SHIFT+O to avoid
    assigning focus to the menu in the main window.
  - Switching from overlay in the main window to popout browser
    window will give focus to the popout browser.
  - Switching from popout browser to overlay will leave current focus
    unchanged (e.g. in the overlay browser, or somewhere else). User
    gesture to activate the main window may be required on Mac/Linux.
- When running with `--no-active` don't give initial focus to either
  browser.

In cefsimple:
- Browser receives initial focus via default handling.
This commit is contained in:
Marshall Greenblatt
2024-11-05 14:58:45 -05:00
parent b070564ec5
commit b660522983
53 changed files with 652 additions and 91 deletions

View File

@@ -12,6 +12,7 @@
#include "include/cef_i18n_util.h"
#include "include/views/cef_box_layout.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefclient/browser/base_client_handler.h"
#include "tests/cefclient/browser/default_client_handler.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/resource.h"
@@ -201,10 +202,7 @@ void ViewsWindow::Show() {
window_->Show();
}
}
if (browser_view_ && !window_->IsMinimized()) {
// Give keyboard focus to the BrowserView.
browser_view_->RequestFocus();
}
MaybeRequestBrowserFocus();
}
void ViewsWindow::Hide() {
@@ -378,6 +376,18 @@ void ViewsWindow::SetDraggableRegions(
window_->SetDraggableRegions(window_regions);
}
bool ViewsWindow::OnSetFocus(cef_focus_source_t source) {
CEF_REQUIRE_UI_THREAD();
// No special handling of focus requests originating from the system.
if (source == FOCUS_SOURCE_SYSTEM) {
return false;
}
RequestBrowserFocus();
return true;
}
void ViewsWindow::TakeFocus(bool next) {
CEF_REQUIRE_UI_THREAD();
@@ -1396,4 +1406,31 @@ void ViewsWindow::NudgeWindow() {
}
#endif
void ViewsWindow::MaybeRequestBrowserFocus() {
if (browser_view_) {
// BaseClientHandler has some state that we need to query.
if (auto handler =
BaseClientHandler::GetForBrowser(browser_view_->GetBrowser());
handler->ShouldRequestFocus()) {
RequestBrowserFocus();
}
}
}
void ViewsWindow::RequestBrowserFocus() {
if (window_->IsMinimized()) {
return;
}
// Maybe give keyboard focus to the overlay BrowserView.
if (overlay_browser_ && overlay_browser_->RequestFocus()) {
return;
}
// Give keyboard focus to the main BrowserView.
if (browser_view_) {
browser_view_->RequestFocus();
}
}
} // namespace client