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.
This commit is contained in:
Marshall Greenblatt 2022-04-11 16:54:33 -04:00
parent 3000bc8748
commit 75ca552a4e
10 changed files with 46 additions and 6 deletions

View File

@ -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));

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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<RootWindow> 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<RootWindow> root_window =
RootWindow::Create(MainContext::Get()->UseViews());
root_window->InitAsPopup(this, with_controls, with_osr, popupFeatures,

View File

@ -265,8 +265,11 @@ ViewsWindow::Delegate* RootWindowViews::GetDelegateForPopup(
RootWindowViews* root_window =
static_cast<RootWindowViews*>(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;
}

View File

@ -344,8 +344,12 @@ CefRefPtr<CefBrowserViewDelegate> 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<ViewsWindow*>(static_cast<CefBrowserViewDelegate*>(
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);

View File

@ -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

View File

@ -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