From 75ca552a4e88e2a27aa9bcbd2568ccede5a220a0 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Mon, 11 Apr 2022 16:54:33 -0400 Subject: [PATCH] cefclient: Add option to create default popups (see issue #3165, see issue #3294) This change adds a `--use-default-popup` command-line option to cefclient. When specified, popup windows will be created with default styling (e.g. without an application-provided native parent window). This change also adds some reasonable default window bounds in cases where they are not specified by the client. --- .../native/browser_platform_delegate_native_win.cc | 5 +++++ libcef/browser/views/window_view.cc | 4 ++++ tests/cefclient/browser/main_context.h | 3 +++ tests/cefclient/browser/main_context_impl.cc | 5 +++++ tests/cefclient/browser/main_context_impl.h | 1 + tests/cefclient/browser/root_window_manager.cc | 13 +++++++++++-- tests/cefclient/browser/root_window_views.cc | 7 +++++-- tests/cefclient/browser/views_window.cc | 12 ++++++++++-- tests/shared/common/client_switches.cc | 1 + tests/shared/common/client_switches.h | 1 + 10 files changed, 46 insertions(+), 6 deletions(-) diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index 7aa418155..5483de40d 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -178,6 +178,11 @@ void CefBrowserPlatformDelegateNativeWin::BrowserDestroyed( bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() { RegisterWindowClass(); + if (window_info_.style == 0) { + // Client didn't intialize the CefWindowInfo. Provide reasonable defaults. + window_info_.SetAsPopup(nullptr, CefString()); + } + has_frame_ = !(window_info_.style & WS_CHILD); std::wstring windowName(CefString(&window_info_.window_name)); diff --git a/libcef/browser/views/window_view.cc b/libcef/browser/views/window_view.cc index 2964c1352..88d775e17 100644 --- a/libcef/browser/views/window_view.cc +++ b/libcef/browser/views/window_view.cc @@ -346,6 +346,10 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) { if (params.bounds.IsEmpty()) { // The window will be placed on the default screen with origin (0,0). params.bounds = gfx::Rect(CalculatePreferredSize()); + if (params.bounds.IsEmpty()) { + // Choose a reasonable default size. + params.bounds.set_size({800, 600}); + } } if (can_activate) { diff --git a/tests/cefclient/browser/main_context.h b/tests/cefclient/browser/main_context.h index b43d29dd0..67d3e3574 100644 --- a/tests/cefclient/browser/main_context.h +++ b/tests/cefclient/browser/main_context.h @@ -51,6 +51,9 @@ class MainContext { // Returns true if touch events are enabled. virtual bool TouchEventsEnabled() = 0; + // Returns true if the default popup implementation should be used. + virtual bool UseDefaultPopup() = 0; + // Populate |settings| based on command-line arguments. virtual void PopulateSettings(CefSettings* settings) = 0; virtual void PopulateBrowserSettings(CefBrowserSettings* settings) = 0; diff --git a/tests/cefclient/browser/main_context_impl.cc b/tests/cefclient/browser/main_context_impl.cc index 68d56275f..cc41ddf50 100644 --- a/tests/cefclient/browser/main_context_impl.cc +++ b/tests/cefclient/browser/main_context_impl.cc @@ -181,6 +181,11 @@ bool MainContextImpl::TouchEventsEnabled() { return command_line_->GetSwitchValue("touch-events") == "enabled"; } +bool MainContextImpl::UseDefaultPopup() { + return !use_windowless_rendering_ && + command_line_->HasSwitch(switches::kUseDefaultPopup); +} + void MainContextImpl::PopulateSettings(CefSettings* settings) { client::ClientAppBrowser::PopulateSettings(command_line_, *settings); diff --git a/tests/cefclient/browser/main_context_impl.h b/tests/cefclient/browser/main_context_impl.h index 15dddd338..d07bc088a 100644 --- a/tests/cefclient/browser/main_context_impl.h +++ b/tests/cefclient/browser/main_context_impl.h @@ -32,6 +32,7 @@ class MainContextImpl : public MainContext { bool UseViews() override; bool UseWindowlessRendering() override; bool TouchEventsEnabled() override; + bool UseDefaultPopup() override; void PopulateSettings(CefSettings* settings) override; void PopulateBrowserSettings(CefBrowserSettings* settings) override; void PopulateOsrSettings(OsrRendererSettings* settings) override; diff --git a/tests/cefclient/browser/root_window_manager.cc b/tests/cefclient/browser/root_window_manager.cc index d3374bc75..cfbc4a338 100644 --- a/tests/cefclient/browser/root_window_manager.cc +++ b/tests/cefclient/browser/root_window_manager.cc @@ -9,6 +9,7 @@ #include "include/base/cef_callback.h" #include "include/base/cef_logging.h" #include "include/wrapper/cef_helpers.h" +#include "tests/cefclient/browser/client_handler_std.h" #include "tests/cefclient/browser/main_context.h" #include "tests/cefclient/browser/test_runner.h" #include "tests/shared/browser/extension_util.h" @@ -130,13 +131,21 @@ scoped_refptr RootWindowManager::CreateRootWindowAsPopup( CefBrowserSettings& settings) { CEF_REQUIRE_UI_THREAD(); + MainContext::Get()->PopulateBrowserSettings(&settings); + + if (MainContext::Get()->UseDefaultPopup()) { + // Use default window creation for the popup. A new |client| instance is + // still required by cefclient architecture. + client = new ClientHandlerStd(/*delegate=*/nullptr, with_controls, + /*startup_url=*/CefString()); + return nullptr; + } + if (!temp_window_) { // TempWindow must be created on the UI thread. temp_window_.reset(new TempWindow()); } - MainContext::Get()->PopulateBrowserSettings(&settings); - scoped_refptr root_window = RootWindow::Create(MainContext::Get()->UseViews()); root_window->InitAsPopup(this, with_controls, with_osr, popupFeatures, diff --git a/tests/cefclient/browser/root_window_views.cc b/tests/cefclient/browser/root_window_views.cc index dcc533293..73a5b1947 100644 --- a/tests/cefclient/browser/root_window_views.cc +++ b/tests/cefclient/browser/root_window_views.cc @@ -265,8 +265,11 @@ ViewsWindow::Delegate* RootWindowViews::GetDelegateForPopup( RootWindowViews* root_window = static_cast(handler->delegate()); - // Transfer some state to the child RootWindowViews. - root_window->image_cache_ = image_cache_; + // May be nullptr when using the default popup behavior. + if (root_window) { + // Transfer some state to the child RootWindowViews. + root_window->image_cache_ = image_cache_; + } return root_window; } diff --git a/tests/cefclient/browser/views_window.cc b/tests/cefclient/browser/views_window.cc index 061fec16d..2b1480912 100644 --- a/tests/cefclient/browser/views_window.cc +++ b/tests/cefclient/browser/views_window.cc @@ -344,8 +344,12 @@ CefRefPtr ViewsWindow::GetDelegateForPopupBrowserView( // knows the association between |client| and itself. Delegate* popup_delegate = delegate_->GetDelegateForPopup(client); + // May be nullptr when using the default popup behavior. + if (!popup_delegate) + return nullptr; + // Should not be the same RootWindowViews that owns |this|. - DCHECK(popup_delegate && popup_delegate != delegate_); + DCHECK(popup_delegate != delegate_); // Create a new ViewsWindow for the popup BrowserView. return new ViewsWindow(popup_delegate, nullptr); @@ -362,8 +366,12 @@ bool ViewsWindow::OnPopupBrowserViewCreated( static_cast(static_cast( popup_browser_view->GetDelegate().get())); + // May be nullptr when using the default popup behavior. + if (!popup_window) + return false; + // Should not be the same ViewsWindow as |this|. - DCHECK(popup_window && popup_window != this); + DCHECK(popup_window != this); // Associate the ViewsWindow with the new popup browser. popup_window->SetBrowserView(popup_browser_view); diff --git a/tests/shared/common/client_switches.cc b/tests/shared/common/client_switches.cc index 679e8d2a8..aaf69ebb3 100644 --- a/tests/shared/common/client_switches.cc +++ b/tests/shared/common/client_switches.cc @@ -49,6 +49,7 @@ const char kEnableChromeRuntime[] = "enable-chrome-runtime"; const char kShowChromeToolbar[] = "show-chrome-toolbar"; const char kInitialShowState[] = "initial-show-state"; const char kHideChromeStatusBubble[] = "hide-chrome-status-bubble"; +const char kUseDefaultPopup[] = "use-default-popup"; } // namespace switches } // namespace client diff --git a/tests/shared/common/client_switches.h b/tests/shared/common/client_switches.h index 4c8eabf89..cadb9438e 100644 --- a/tests/shared/common/client_switches.h +++ b/tests/shared/common/client_switches.h @@ -43,6 +43,7 @@ extern const char kEnableChromeRuntime[]; extern const char kShowChromeToolbar[]; extern const char kInitialShowState[]; extern const char kHideChromeStatusBubble[]; +extern const char kUseDefaultPopup[]; } // namespace switches } // namespace client