Files
cef/libcef/browser/chrome/chrome_browser_delegate.h
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

172 lines
7.6 KiB
C++

// Copyright 2020 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.
#ifndef CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_
#pragma once
#include <memory>
#include <optional>
#include "libcef/browser/browser_host_base.h"
#include "libcef/browser/browser_info.h"
#include "libcef/browser/chrome/browser_delegate.h"
class CefBrowserContentsDelegate;
class CefRequestContextImpl;
class CefWindowImpl;
class CefWindowView;
class ChromeBrowserHostImpl;
// Implementation of the cef::BrowserDelegate interface. Lifespan is controlled
// by the Browser object. Only accessed on the UI thread.
//
// The Browser object represents the top-level Chrome browser window. One or
// more tabs (WebContents) are then owned by the Browser object via
// TabStripModel. A new Browser object can be created programmatically using
// "new Browser" or Browser::Create, or as a result of user action such as
// dragging a tab out of an existing window. New or existing tabs can also be
// added to an already existing Browser object.
//
// The Browser object acts as the WebContentsDelegate for all attached tabs. CEF
// integration requires WebContentsDelegate callbacks and notification of tab
// attach/detach. To support this integration a cef::BrowserDelegate
// (ChromeBrowserDelegate) member is created in the Browser constructor and
// receives delegation for the Browser callbacks. ChromeBrowserDelegate creates
// a new ChromeBrowserHostImpl when a tab is added to a Browser for the first
// time, and that ChromeBrowserHostImpl continues to exist until the tab's
// WebContents is destroyed. The associated WebContents object does not change,
// but the Browser object will change when the tab is dragged between windows.
class ChromeBrowserDelegate : public cef::BrowserDelegate {
public:
// The |create_params| and |opener| values are specified via the
// Browser::CreateParams passed to Browser::Create. |opener| will only be
// specified for certain special Browser types.
ChromeBrowserDelegate(Browser* browser,
const CefBrowserCreateParams& create_params,
const Browser* opener);
ChromeBrowserDelegate(const ChromeBrowserDelegate&) = delete;
ChromeBrowserDelegate& operator=(const ChromeBrowserDelegate&) = delete;
~ChromeBrowserDelegate() override;
static Browser* CreateDevToolsBrowser(
Profile* profile,
Browser* opener,
content::WebContents* inspected_web_contents,
std::unique_ptr<content::WebContents>& devtools_contents);
// cef::BrowserDelegate methods:
std::unique_ptr<content::WebContents> AddWebContents(
std::unique_ptr<content::WebContents> new_contents) override;
void OnWebContentsCreated(content::WebContents* new_contents) override;
void SetAsDelegate(content::WebContents* web_contents,
bool set_delegate) override;
bool ShowStatusBubble(bool show_by_default) override;
bool HandleCommand(int command_id,
WindowOpenDisposition disposition) override;
bool IsAppMenuItemVisible(int command_id) override;
bool IsAppMenuItemEnabled(int command_id) override;
bool IsPageActionIconVisible(PageActionIconType icon_type) override;
bool IsToolbarButtonVisible(ToolbarButtonType button_type) override;
void UpdateFindBarBoundingBox(gfx::Rect* bounds) override;
void UpdateDialogTopInset(int* dialog_top_y) override;
[[nodiscard]] content::MediaResponseCallback RequestMediaAccessPermissionEx(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
content::MediaResponseCallback callback) override;
bool RendererUnresponsiveEx(
content::WebContents* source,
content::RenderWidgetHost* render_widget_host,
base::RepeatingClosure hang_monitor_restarter) override;
bool RendererResponsiveEx(
content::WebContents* source,
content::RenderWidgetHost* render_widget_host) override;
std::optional<bool> SupportsWindowFeature(int feature) const override;
bool SupportsDraggableRegion() const override;
const std::optional<SkRegion> GetDraggableRegion() const override;
void UpdateDraggableRegion(const SkRegion& region) override;
void WindowFullscreenStateChanged() override;
bool HasViewsHostedOpener() const override;
// WebContentsDelegate methods:
void WebContentsCreated(content::WebContents* source_contents,
int opener_render_process_id,
int opener_render_frame_id,
const std::string& frame_name,
const GURL& target_url,
content::WebContents* new_contents) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;
void LoadingStateChanged(content::WebContents* source,
bool should_show_loading_ui) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
bool DidAddMessageToConsole(content::WebContents* source,
blink::mojom::ConsoleMessageLevel log_level,
const std::u16string& message,
int32_t line_no,
const std::u16string& source_id) override;
void EnterFullscreenModeForTab(
content::RenderFrameHost* requesting_frame,
const blink::mojom::FullscreenOptions& options) override;
void ExitFullscreenModeForTab(content::WebContents* web_contents) override;
void CanDownload(const GURL& url,
const std::string& request_method,
base::OnceCallback<void(bool)> callback) override;
content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
bool HandleKeyboardEvent(
content::WebContents* source,
const content::NativeWebKeyboardEvent& event) override;
Browser* browser() const { return browser_; }
private:
static CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHost(
Browser* browser,
content::WebContents* web_contents,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
scoped_refptr<CefBrowserInfo> browser_info,
bool is_devtools_popup,
CefRefPtr<CefBrowserHostBase> opener,
CefRefPtr<CefRequestContextImpl> request_context_impl);
static CefRefPtr<ChromeBrowserHostImpl> CreateBrowserHostForPopup(
content::WebContents* web_contents,
const CefBrowserSettings& settings,
CefRefPtr<CefClient> client,
CefRefPtr<CefDictionaryValue> extra_info,
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate,
bool is_devtools_popup,
CefRefPtr<CefBrowserHostBase> opener);
CefBrowserContentsDelegate* GetDelegateForWebContents(
content::WebContents* web_contents) const;
bool SupportsFramelessPictureInPicture() const;
bool IsViewsHosted() const;
// Will return nullptr if the Browser is not Views-hosted.
CefWindowImpl* GetCefWindowImpl() const;
CefWindowView* GetCefWindowView() const;
Browser* const browser_;
base::WeakPtr<ChromeBrowserHostImpl> opener_host_;
// Used when creating a new browser host.
const CefBrowserCreateParams create_params_;
std::optional<bool> show_status_bubble_;
std::optional<SkRegion> draggable_region_;
mutable std::optional<bool> frameless_pip_;
};
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_BROWSER_DELEGATE_H_