cef/tests/cefsimple/simple_app.cc
Marshall Greenblatt dca0435d2f chrome: Add support for Alloy style browsers and windows (see #3681)
Split the Alloy runtime into bootstrap and style components. Support
creation of Alloy style browsers and windows with the Chrome runtime.
Chrome runtime (`--enable-chrome-runtime`) + Alloy style
(`--use-alloy-style`) supports Views (`--use-views`), native parent
(`--use-native`) and windowless rendering
(`--off-screen-rendering-enabled`).

Print preview is supported in all cases except with windowless rendering
on all platforms and native parent on MacOS. It is disabled by default
with Alloy style for legacy compatibility. Where supported it can be
enabled or disabled globally using `--[enable|disable]-print-preview` or
configured on a per-RequestContext basis using the
`printing.print_preview_disabled` preference. It also behaves as
expected when triggered via the PDF viewer print button.

Chrome runtime + Alloy style behavior differs from Alloy runtime in the
following significant ways:

- Supports Chrome error pages by default.
- DevTools popups are Chrome style only (cannot be windowless).
- The Alloy extension API will not supported.

Chrome runtime + Alloy style passes all expected Alloy ceftests except
the following:

- `DisplayTest.AutoResize` (Alloy extension API not supported)
- `DownloadTest.*` (Download API not yet supported)
- `ExtensionTest.*` (Alloy extension API not supported)

This change also adds Chrome runtime support for
CefContextMenuHandler::RunContextMenu (see #3293).

This change also explicitly blocks (and doesn't retry) FrameAttached
requests from PDF viewer and print preview excluded frames (see #3664).

Known issues specific to Chrome runtime + Alloy style:
- DevTools popup with windowless rendering doesn't load successfully.
  Use windowed rendering or remote debugging as a workaround.
- Chrome style Window with Alloy style BrowserView (`--use-alloy-style
  --use-chrome-style-window`) does not show Chrome theme changes.

To test:
- Run `ceftests --enable-chrome-runtime --use-alloy-style
       [--use-chrome-style-window] [--use-views|--use-native]
       --gtest_filter=...`
- Run `cefclient --enable-chrome-runtime --use-alloy-style
       [--use-chrome-style-window]
       [--use-views|--use-native|--off-screen-rendering-enabled]`
- Run `cefsimple --enable-chrome-runtime --use-alloy-style [--use-views]`
2024-04-22 14:57:37 -04:00

194 lines
6.3 KiB
C++

// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "tests/cefsimple/simple_app.h"
#include <string>
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefsimple/simple_handler.h"
namespace {
// When using the Views framework this object provides the delegate
// implementation for the CefWindow that hosts the Views-based browser.
class SimpleWindowDelegate : public CefWindowDelegate {
public:
SimpleWindowDelegate(CefRefPtr<CefBrowserView> browser_view,
cef_runtime_style_t runtime_style,
cef_show_state_t initial_show_state)
: browser_view_(browser_view),
runtime_style_(runtime_style),
initial_show_state_(initial_show_state) {}
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
// Add the browser view and show the window.
window->AddChildView(browser_view_);
if (initial_show_state_ != CEF_SHOW_STATE_HIDDEN) {
window->Show();
}
if (initial_show_state_ != CEF_SHOW_STATE_MINIMIZED &&
initial_show_state_ != CEF_SHOW_STATE_HIDDEN) {
// Give keyboard focus to the browser view.
browser_view_->RequestFocus();
}
}
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
browser_view_ = nullptr;
}
bool CanClose(CefRefPtr<CefWindow> window) override {
// Allow the window to close if the browser says it's OK.
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
if (browser) {
return browser->GetHost()->TryCloseBrowser();
}
return true;
}
CefSize GetPreferredSize(CefRefPtr<CefView> view) override {
return CefSize(800, 600);
}
cef_show_state_t GetInitialShowState(CefRefPtr<CefWindow> window) override {
return initial_show_state_;
}
cef_runtime_style_t GetWindowRuntimeStyle() override {
return runtime_style_;
}
private:
CefRefPtr<CefBrowserView> browser_view_;
const cef_runtime_style_t runtime_style_;
const cef_show_state_t initial_show_state_;
IMPLEMENT_REFCOUNTING(SimpleWindowDelegate);
DISALLOW_COPY_AND_ASSIGN(SimpleWindowDelegate);
};
class SimpleBrowserViewDelegate : public CefBrowserViewDelegate {
public:
explicit SimpleBrowserViewDelegate(cef_runtime_style_t runtime_style)
: runtime_style_(runtime_style) {}
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
CefRefPtr<CefBrowserView> popup_browser_view,
bool is_devtools) override {
// Create a new top-level Window for the popup. It will show itself after
// creation.
CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(
popup_browser_view, runtime_style_, CEF_SHOW_STATE_NORMAL));
// We created the Window.
return true;
}
cef_runtime_style_t GetBrowserRuntimeStyle() override {
return runtime_style_;
}
private:
const cef_runtime_style_t runtime_style_;
IMPLEMENT_REFCOUNTING(SimpleBrowserViewDelegate);
DISALLOW_COPY_AND_ASSIGN(SimpleBrowserViewDelegate);
};
} // namespace
SimpleApp::SimpleApp() = default;
void SimpleApp::OnContextInitialized() {
CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
// Check if Alloy style will be used. Alloy style is always used with the
// Alloy runtime bootstrap and optional with the Chrome runtime bootstrap.
bool use_alloy_style = true;
cef_runtime_style_t runtime_style = CEF_RUNTIME_STYLE_DEFAULT;
if (command_line->HasSwitch("enable-chrome-runtime")) {
use_alloy_style = command_line->HasSwitch("use-alloy-style");
if (use_alloy_style) {
runtime_style = CEF_RUNTIME_STYLE_ALLOY;
}
}
// SimpleHandler implements browser-level callbacks.
CefRefPtr<SimpleHandler> handler(new SimpleHandler(use_alloy_style));
// Specify CEF browser settings here.
CefBrowserSettings browser_settings;
std::string url;
// Check if a "--url=" value was provided via the command-line. If so, use
// that instead of the default URL.
url = command_line->GetSwitchValue("url");
if (url.empty()) {
url = "http://www.google.com";
}
// Create the browser using the Views framework if "--use-views" is specified
// via the command-line. Otherwise, create the browser using the native
// platform framework.
if (command_line->HasSwitch("use-views")) {
// Create the BrowserView.
CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
handler, url, browser_settings, nullptr, nullptr,
new SimpleBrowserViewDelegate(runtime_style));
// Optionally configure the initial show state.
cef_show_state_t initial_show_state = CEF_SHOW_STATE_NORMAL;
const std::string& show_state_value =
command_line->GetSwitchValue("initial-show-state");
if (show_state_value == "minimized") {
initial_show_state = CEF_SHOW_STATE_MINIMIZED;
} else if (show_state_value == "maximized") {
initial_show_state = CEF_SHOW_STATE_MAXIMIZED;
}
#if defined(OS_MAC)
// Hidden show state is only supported on MacOS.
else if (show_state_value == "hidden") {
initial_show_state = CEF_SHOW_STATE_HIDDEN;
}
#endif
// Create the Window. It will show itself after creation.
CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(
browser_view, runtime_style, initial_show_state));
} else {
// Information used when creating the native window.
CefWindowInfo window_info;
#if defined(OS_WIN)
// On Windows we need to specify certain flags that will be passed to
// CreateWindowEx().
window_info.SetAsPopup(nullptr, "cefsimple");
#endif
// Alloy runtime style will create a basic native window. Chrome runtime
// style will create a fully styled Chrome UI window.
window_info.runtime_style = runtime_style;
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings,
nullptr, nullptr);
}
}
CefRefPtr<CefClient> SimpleApp::GetDefaultClient() {
// Called when a new browser window is created via the Chrome runtime UI.
return SimpleHandler::GetInstance();
}