Compare commits

...

25 Commits
6367 ... 5790

Author SHA1 Message Date
Marshall Greenblatt
21130e0144 Update to Chromium version 115.0.5790.173 2023-08-15 13:01:34 +00:00
Marshall Greenblatt
91e8c06f29 Update to Chromium version 115.0.5790.172 2023-08-11 01:41:22 +00:00
Marshall Greenblatt
749b4d4340 Update depot_tools version to fix gclient sync error
Fixes Error: 91> Wrong keys 'git_dependencies'
2023-08-07 16:27:46 +00:00
Marshall Greenblatt
fcd259c3e0 Update to Chromium version 115.0.5790.171 2023-08-03 17:12:09 +00:00
Marshall Greenblatt
a61da9b80c Update to Chromium version 115.0.5790.114 2023-07-27 13:40:27 +00:00
Marshall Greenblatt
9cc8df1534 Update to Chromium version 115.0.5790.102 2023-07-24 15:43:53 +00:00
Marshall Greenblatt
aa348cb3de Update to Chromium version 115.0.5790.99 2023-07-20 15:28:39 -04:00
Marshall Greenblatt
75c3bf0480 Don't run UI thread tasks after calling CefQuitMessageLoop
This avoids a situation where misbehaving clients may cause the
application to continue running indefinitely by posting new UI
thread tasks after calling CefQuitMessageLoop.
2023-07-11 16:19:50 +03:00
Marshall Greenblatt
a8d552a01b cefclient: mac: Fix type conversion error with Xcode 2023-07-06 13:22:48 +03:00
Marshall Greenblatt
89aff51c04 chrome: linux: Fix NativeWidgetType for bubble popups 2023-07-04 20:57:03 +03:00
Marshall Greenblatt
4e9a80a23d chrome: mac: Keep bubble popups on-screen 2023-07-04 20:56:52 +03:00
Marshall Greenblatt
557c3ad6e7 cefclient: views: Add option for bottom controls placement
Run with the `--use-bottom-controls` command-line flag to place all controls
at the bottom of the window instead of the top.
2023-07-04 20:56:17 +03:00
Marshall Greenblatt
521608d3c2 linux: Fix invalid argument type in CHECK 2023-06-28 22:01:25 +03:00
Marshall Greenblatt
d1d2d6a532 tests: Fix timing issue with DownloadTest.ClickedInvalid 2023-06-28 22:01:25 +03:00
Marshall Greenblatt
419ffdb122 Update to Chromium version 115.0.5790.40 2023-06-22 07:04:54 +00:00
Marshall Greenblatt
5dbfe13ac8 views: Add support for modal browser dialogs
A modal dialog is a child CefWindow that implements some special behaviors
relative to a parent CefWindow. Like any CefWindow it can be framed with
titlebar or frameless, and optionally contain draggable regions (subject to
platform limitations described below). Modal dialogs are shown centered on
the parent window (inside a single display) and always stay on top of the
parent window in z-order. Sizing behavior and available window buttons are
controlled via the usual CefWindowDelegate callbacks. For example, the dialog
can have a preferred size with resize, minimize and maximize disabled (via
GetPreferredSize, CanResize, CanMinimize and CanMaximize respectively).

This change adds support for two modality modes. With window modality all
controls in the parent window are disabled. With browser modality only the
browser view in the parent window is disabled.

Both modality modes require that a valid parent window be returned via
GetParentWindow. For window modality return true from IsWindowModalDialog
and call CefWindow::Show. For browser modality return false from
IsWindowModalDialog (the default value) and call
CefWindow::ShowAsBrowserModalDialog with a reference to the parent window's
browser view.

Window modal dialog behavior depends on the platform. On Windows and
Linux these dialogs have a titlebar and can be moved independent of the
parent window. On macOS these dialogs do not have a titlebar, move with
the parent window, and do not support draggable regions (because they are
implemented using sheets). On Linux disabling the parent window controls
requires a window manager the supports _NET_WM_STATE_MODAL.

Browser modal dialog behavior is similar on all platforms. The dialog will
be automatically sized and positioned relative to the parent window's
browser view. Closing the parent window or navigating the parent browser
view will dismiss the dialog. The dialog can also be moved independent of
the parent window though it will be recentered when the parent window
itself is resized or redisplayed. On MacOS the dialog will move along with
the parent window while on Windows and Linux the parent window can be moved
independently.

To test: Use the Tests > Dialog Window menu option in cefclient with Views
enabled (`--use-views` or `--enable-chrome-runtime` command-line flag).
Browser modal dialog is the default behavior. For window modal dialog add
the `--use-window-modal-dialog` command-line flag.
2023-06-21 11:59:11 +03:00
Marshall Greenblatt
061204d5be views: win: Use black title bar with dark mode 2023-06-21 11:59:11 +03:00
Marshall Greenblatt
cf87de98bc Update to Chromium version 115.0.5790.32 2023-06-16 07:35:27 +00:00
Marshall Greenblatt
ed5af5272d Update to Chromium version 115.0.5790.24 2023-06-12 07:45:13 +00:00
Marshall Greenblatt
be022e26bc mac: Fix char16_t declaration error with Xcode 14.2 (fixes #3526) 2023-06-07 13:27:00 +03:00
Marshall Greenblatt
096e3eb30d alloy: Remove CefSettings.user_data_path (fixes #3511)
This change replaces existing CefSettings.user_data_path usage with
CefSettings.root_cache_path for better alignment with the Chrome runtime.
All files should now be written inside the root_cache_path directory.
2023-06-06 18:45:53 +03:00
Chris Frank
7bcc232ecf linux: alloy: Fix window resize after context menu dismissal (fixes #3466) 2023-06-06 15:35:09 +03:00
Marshall Greenblatt
30c8e3634d mac: Fix <uchar.h> not available with Xcode < 14.3 (fixes #3526) 2023-06-06 14:57:08 +03:00
Marshall Greenblatt
82da225a9f mac: chrome: Fix crash in BrowserView::ShouldHideUIForFullscreen (fixes #3527) 2023-06-06 12:22:58 +03:00
Marshall Greenblatt
e43eab3229 Update to Chromium version 115.0.5790.13 2023-06-03 12:22:04 +03:00
73 changed files with 1133 additions and 365 deletions

View File

@@ -801,6 +801,7 @@ source_set("libcef_static") {
"libcef/browser/views/view_util.cc",
"libcef/browser/views/view_util.h",
"libcef/browser/views/view_view.h",
"libcef/browser/views/widget_destruction_observer.h",
"libcef/browser/views/window_impl.cc",
"libcef/browser/views/window_impl.h",
"libcef/browser/views/window_view.cc",

View File

@@ -7,5 +7,6 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/115.0.5790.0'
'chromium_checkout': 'refs/tags/115.0.5790.173',
'depot_tools_checkout': '6d0c235dae'
}

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=5c6e0b9e37b8103a182f200fccdf5973104fcd70$
// $hash=22cfd717df9032a01214d9abfe3e0e51949b3319$
//
#ifndef CEF_INCLUDE_CAPI_CEF_CRASH_UTIL_CAPI_H_
@@ -90,7 +90,7 @@ extern "C" {
/// If "AppName" is set on Windows then crash report information (metrics,
/// database and dumps) will be stored locally on disk under the
/// "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder. On other
/// platforms the cef_settings_t.user_data_path value will be used.
/// platforms the cef_settings_t.root_cache_path value will be used.
///
/// If "ExternalHandler" is set on Windows then the specified exe will be
/// launched as the crashpad-handler instead of re-launching the main process

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=e09c33a3604cb7a80ef7fdea72c838619e26dc8c$
// $hash=d53c4a0a7e731a56a0edcb9d705c76b0a2770155$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_
@@ -51,6 +51,8 @@
extern "C" {
#endif
struct _cef_browser_view_t;
///
/// A Window is a top-level Window/widget in the Views hierarchy. By default it
/// will have a non-client area with title bar, icon and buttons that supports
@@ -69,6 +71,21 @@ typedef struct _cef_window_t {
///
void(CEF_CALLBACK* show)(struct _cef_window_t* self);
///
/// Show the Window as a browser modal dialog relative to |browser_view|. A
/// parent Window must be returned via
/// cef_window_delegate_t::get_parent_window() and |browser_view| must belong
/// to that parent Window. While this Window is visible, |browser_view| will
/// be disabled while other controls in the parent Window remain enabled.
/// Navigating or destroying the |browser_view| will close this Window
/// automatically. Alternately, use show() and return true (1) from
/// cef_window_delegate_t::is_window_modal_dialog() for a window modal dialog
/// where all controls in the parent Window are disabled.
///
void(CEF_CALLBACK* show_as_browser_modal_dialog)(
struct _cef_window_t* self,
struct _cef_browser_view_t* browser_view);
///
/// Hide the Window.
///

View File

@@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
// $hash=7201d268e16fc89f255b6ccd00d043f34fe77584$
// $hash=61099a1ba8b16a5e46f5a80d326d1f9bfc99317d$
//
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
@@ -110,6 +110,18 @@ typedef struct _cef_window_delegate_t {
int* is_menu,
int* can_activate_menu);
///
/// Return true (1) if |window| should be created as a window modal dialog.
/// Only called when a Window is returned via get_parent_window() with
/// |is_menu| set to false (0). All controls in the parent Window will be
/// disabled while |window| is visible. This functionality is not supported by
/// all Linux window managers. Alternately, use
/// cef_window_t::show_as_browser_modal_dialog() for a browser modal dialog
/// that works on all platforms.
///
int(CEF_CALLBACK* is_window_modal_dialog)(struct _cef_window_delegate_t* self,
struct _cef_window_t* window);
///
/// Return the initial bounds for |window| in density independent pixel (DIP)
/// coordinates. If this function returns an NULL CefRect then

View File

@@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "ea590fbd1cbe2c80698a52efb712357a307fee34"
#define CEF_API_HASH_UNIVERSAL "9c9fbc9d59a544c8e0c2f0cbed4b6622f2786f1c"
#if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "8a76490c640051ed3500b3b19035be58daf755f7"
#define CEF_API_HASH_PLATFORM "240e06747f2ea2d7d4a3071042d45cf80d170420"
#elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "725ff527623c12c783b999212b01f5d721622779"
#define CEF_API_HASH_PLATFORM "cd4a815153a919ad30b95c659688b564823d92fc"
#elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "52bd91427e6857b3f43a3bed552703d210927cff"
#define CEF_API_HASH_PLATFORM "4c372cb13e3446b2a54aaaea51b0d47ba7766152"
#endif
#ifdef __cplusplus

View File

@@ -82,7 +82,7 @@
/// If "AppName" is set on Windows then crash report information (metrics,
/// database and dumps) will be stored locally on disk under the
/// "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder. On other
/// platforms the cef_settings_t.user_data_path value will be used.
/// platforms the cef_settings_t.root_cache_path value will be used.
///
/// If "ExternalHandler" is set on Windows then the specified exe will be
/// launched as the crashpad-handler instead of re-launching the main process

View File

@@ -32,7 +32,18 @@
#pragma once
#include <stddef.h>
#ifdef __clang__
// On macOS, <uchar.h> is only available with Xcode 14.3+.
#if __has_include(<uchar.h>)
#include <uchar.h>
#elif !defined(__cplusplus)
#include <stdint.h>
typedef uint_least16_t char16_t;
#endif
#else
#include <uchar.h>
#endif
#include "include/internal/cef_export.h"

View File

@@ -34,7 +34,6 @@
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <uchar.h>
#include "include/internal/cef_string.h"
#include "include/internal/cef_string_list.h"
@@ -261,24 +260,16 @@ typedef struct _cef_settings_t {
/// The root directory that all CefSettings.cache_path and
/// CefRequestContextSettings.cache_path values must have in common. If this
/// value is empty and CefSettings.cache_path is non-empty then it will
/// default to the CefSettings.cache_path value. If this value is non-empty
/// then it must be an absolute path. Failure to set this value correctly may
/// result in the sandbox blocking read/write access to the cache_path
/// directory.
///
cef_string_t root_cache_path;
///
/// The location where user data such as the Widevine CDM module and spell
/// checking dictionary files will be stored on disk. If this value is empty
/// then the default platform-specific user data directory will be used
/// default to the CefSettings.cache_path value. If both values are empty
/// then the default platform-specific directory will be used
/// ("~/.config/cef_user_data" directory on Linux, "~/Library/Application
/// Support/CEF/User Data" directory on MacOS, "AppData\Local\CEF\User Data"
/// directory under the user profile directory on Windows). If this value is
/// non-empty then it must be an absolute path. When using the Chrome runtime
/// this value will be ignored in favor of the |root_cache_path| value.
/// non-empty then it must be an absolute path. Failure to set this value
/// correctly may result in the sandbox blocking read/write access to certain
/// files.
///
cef_string_t user_data_path;
cef_string_t root_cache_path;
///
/// To persist session cookies (cookies without an expiry date or validity

View File

@@ -364,7 +364,6 @@ struct CefSettingsTraits {
cef_string_clear(&s->main_bundle_path);
cef_string_clear(&s->cache_path);
cef_string_clear(&s->root_cache_path);
cef_string_clear(&s->user_data_path);
cef_string_clear(&s->user_agent);
cef_string_clear(&s->user_agent_product);
cef_string_clear(&s->locale);
@@ -397,8 +396,6 @@ struct CefSettingsTraits {
&target->cache_path, copy);
cef_string_set(src->root_cache_path.str, src->root_cache_path.length,
&target->root_cache_path, copy);
cef_string_set(src->user_data_path.str, src->user_data_path.length,
&target->user_data_path, copy);
target->persist_session_cookies = src->persist_session_cookies;
target->persist_user_preferences = src->persist_user_preferences;

View File

@@ -45,6 +45,8 @@
#include "include/views/cef_panel.h"
#include "include/views/cef_window_delegate.h"
class CefBrowserView;
///
/// A Window is a top-level Window/widget in the Views hierarchy. By default it
/// will have a non-client area with title bar, icon and buttons that supports
@@ -68,6 +70,20 @@ class CefWindow : public CefPanel {
/*--cef()--*/
virtual void Show() = 0;
///
/// Show the Window as a browser modal dialog relative to |browser_view|. A
/// parent Window must be returned via CefWindowDelegate::GetParentWindow()
/// and |browser_view| must belong to that parent Window. While this Window is
/// visible, |browser_view| will be disabled while other controls in the
/// parent Window remain enabled. Navigating or destroying the |browser_view|
/// will close this Window automatically. Alternately, use Show() and return
/// true from CefWindowDelegate::IsWindowModalDialog() for a window modal
/// dialog where all controls in the parent Window are disabled.
///
/*--cef()--*/
virtual void ShowAsBrowserModalDialog(
CefRefPtr<CefBrowserView> browser_view) = 0;
///
/// Hide the Window.
///

View File

@@ -99,6 +99,19 @@ class CefWindowDelegate : public CefPanelDelegate {
return nullptr;
}
///
/// Return true if |window| should be created as a window modal dialog. Only
/// called when a Window is returned via GetParentWindow() with |is_menu| set
/// to false. All controls in the parent Window will be disabled while
/// |window| is visible. This functionality is not supported by all Linux
/// window managers. Alternately, use CefWindow::ShowAsBrowserModalDialog()
/// for a browser modal dialog that works on all platforms.
///
/*--cef()--*/
virtual bool IsWindowModalDialog(CefRefPtr<CefWindow> window) {
return false;
}
///
/// Return the initial bounds for |window| in density independent pixel (DIP)
/// coordinates. If this method returns an empty CefRect then

View File

@@ -32,6 +32,7 @@
#include "chrome/browser/ui/color/chrome_color_mixers.h"
#include "chrome/browser/ui/javascript_dialogs/chrome_javascript_app_modal_dialog_view_factory.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "components/constrained_window/constrained_window_views.h"
#include "content/public/browser/gpu_data_manager.h"
@@ -58,6 +59,7 @@
#if BUILDFLAG(IS_WIN)
#include "base/enterprise_util.h"
#include "base/files/file_util.h"
#include "chrome/browser/chrome_browser_main_win.h"
#include "chrome/browser/win/parental_controls.h"
#endif
@@ -82,7 +84,6 @@
#include "base/path_service.h"
#include "chrome/browser/themes/theme_service_aura_linux.h"
#include "chrome/browser/ui/views/theme_profile_key.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/grit/chromium_strings.h"
#include "components/os_crypt/sync/key_storage_config_linux.h"
#include "libcef/browser/printing/print_dialog_linux.h"
@@ -241,6 +242,10 @@ void AlloyBrowserMainParts::PostCreateMainMessageLoop() {
DCHECK(!config->user_data_path.empty());
OSCrypt::SetConfig(std::move(config));
#endif // BUILDFLAG(IS_LINUX)
#if BUILDFLAG(IS_WIN)
base::SetExtraNoExecuteAllowedPath(chrome::DIR_USER_DATA);
#endif
}
int AlloyBrowserMainParts::PreCreateThreads() {

View File

@@ -300,11 +300,11 @@ void BindNetworkHintsHandler(
predictors::NetworkHintsHandlerImpl::Create(frame_host, std::move(receiver));
}
base::FilePath GetRootCachePath() {
// The CefContext::ValidateCachePath method enforces the requirement that all
// cache_path values be either equal to or a child of root_cache_path.
return base::FilePath(
CefString(&CefContext::Get()->settings().root_cache_path));
base::FilePath GetUserDataPath() {
base::FilePath user_data_path;
base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path);
DCHECK(!user_data_path.empty());
return user_data_path;
}
const extensions::Extension* GetEnabledExtensionFromSiteURL(
@@ -1159,19 +1159,7 @@ bool AlloyContentBrowserClient::ConfigureNetworkContextParams(
// directories that are not returned by this method.
std::vector<base::FilePath>
AlloyContentBrowserClient::GetNetworkContextsParentDirectory() {
base::FilePath user_data_path;
base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path);
DCHECK(!user_data_path.empty());
const auto& root_cache_path = GetRootCachePath();
// root_cache_path may sometimes be empty or a child of user_data_path, so
// only return the one path in that case.
if (root_cache_path.empty() || user_data_path.IsParent(root_cache_path)) {
return {user_data_path};
}
return {user_data_path, root_cache_path};
return {GetUserDataPath()};
}
bool AlloyContentBrowserClient::HandleExternalProtocol(
@@ -1282,7 +1270,7 @@ void AlloyContentBrowserClient::RegisterBrowserInterfaceBindersForServiceWorker(
base::FilePath
AlloyContentBrowserClient::GetSandboxedStorageServiceDataDirectory() {
return GetRootCachePath();
return GetUserDataPath();
}
std::string AlloyContentBrowserClient::GetProduct() {

View File

@@ -16,6 +16,7 @@
#include "libcef/common/extensions/extensions_util.h"
#include "base/command_line.h"
#include "base/path_service.h"
#include "chrome/browser/component_updater/chrome_component_updater_configurator.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/permissions/chrome_permissions_client.h"
@@ -24,6 +25,7 @@
#include "chrome/browser/printing/print_job_manager.h"
#include "chrome/browser/printing/print_preview_dialog_controller.h"
#include "chrome/browser/ui/prefs/pref_watcher.h"
#include "chrome/common/chrome_paths.h"
#include "components/component_updater/component_updater_service.h"
#include "components/component_updater/timer_update_scheduler.h"
#include "components/net_log/chrome_net_log.h"
@@ -186,16 +188,15 @@ ProfileManager* ChromeBrowserProcessAlloy::profile_manager() {
PrefService* ChromeBrowserProcessAlloy::local_state() {
DCHECK(initialized_);
if (!local_state_) {
// Use a location that is shared by all request contexts.
const CefSettings& settings = CefContext::Get()->settings();
const base::FilePath& root_cache_path =
base::FilePath(CefString(&settings.root_cache_path));
base::FilePath user_data_path;
base::PathService::Get(chrome::DIR_USER_DATA, &user_data_path);
DCHECK(!user_data_path.empty());
// Used for very early NetworkService initialization.
// Always persist preferences for this PrefService if possible because it
// contains the cookie encryption key on Windows.
local_state_ =
browser_prefs::CreatePrefService(nullptr /* profile */, root_cache_path,
browser_prefs::CreatePrefService(nullptr /* profile */, user_data_path,
true /* persist_user_preferences */);
}
return local_state_.get();

View File

@@ -462,7 +462,6 @@ bool CefContext::Initialize(const CefMainArgs& args,
"browser_subprocess_path");
NormalizePathAndSet(settings_.framework_dir_path, "framework_dir_path");
NormalizePathAndSet(settings_.main_bundle_path, "main_bundle_path");
NormalizePathAndSet(settings_.user_data_path, "user_data_path");
NormalizePathAndSet(settings_.resources_dir_path, "resources_dir_path");
NormalizePathAndSet(settings_.locales_dir_path, "locales_dir_path");

View File

@@ -273,8 +273,8 @@ void CefMainRunner::Shutdown(base::OnceClosure shutdown_on_ui_thread,
void CefMainRunner::RunMessageLoop() {
base::RunLoop run_loop;
DCHECK(quit_when_idle_callback_.is_null());
quit_when_idle_callback_ = run_loop.QuitWhenIdleClosure();
DCHECK(quit_callback_.is_null());
quit_callback_ = run_loop.QuitClosure();
main_delegate_->BeforeMainMessageLoopRun(&run_loop);
@@ -283,11 +283,11 @@ void CefMainRunner::RunMessageLoop() {
}
void CefMainRunner::QuitMessageLoop() {
if (!quit_when_idle_callback_.is_null()) {
if (!quit_callback_.is_null()) {
if (main_delegate_->HandleMainMessageLoopQuit()) {
return;
}
std::move(quit_when_idle_callback_).Run();
std::move(quit_callback_).Run();
}
}

View File

@@ -89,7 +89,7 @@ class CefMainRunner : public CefMainRunnerHandler {
std::unique_ptr<CefUIThread> ui_thread_;
// Used to quit the current base::RunLoop.
base::OnceClosure quit_when_idle_callback_;
base::OnceClosure quit_callback_;
};
#endif // CEF_LIBCEF_BROWSER_MAIN_RUNNER_H_

View File

@@ -127,6 +127,7 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostBase> browser,
/*visual_has_alpha=*/nullptr);
xwindow_ = connection_->GenerateId<x11::Window>();
connection_->CreateWindow({
.depth = depth,
.wid = xwindow_,
@@ -140,12 +141,15 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostBase> browser,
.background_pixel = 0,
.border_pixel = 0,
.override_redirect = x11::Bool32(false),
.event_mask = x11::EventMask::FocusChange |
x11::EventMask::StructureNotify |
x11::EventMask::PropertyChange,
.colormap = colormap,
});
auto event_mask = x11::EventMask::FocusChange |
x11::EventMask::StructureNotify |
x11::EventMask::PropertyChange;
xwindow_events_ =
std::make_unique<x11::XScopedEventSelector>(xwindow_, event_mask);
connection_->Flush();
DCHECK(ui::X11EventSource::HasInstance());

View File

@@ -15,16 +15,16 @@ namespace view_util {
gfx::NativeWindow GetNativeWindow(views::Widget* widget) {
if (widget) {
aura::Window* window = widget->GetNativeWindow();
if (window) {
return window->GetRootWindow();
}
return widget->GetNativeWindow();
}
return nullptr;
}
gfx::NativeView GetNativeView(views::Widget* widget) {
return GetNativeWindow(widget);
if (widget) {
return widget->GetNativeView();
}
return nullptr;
}
CefWindowHandle GetWindowHandle(views::Widget* widget) {

View File

@@ -0,0 +1,34 @@
// Copyright 2023 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 "base/scoped_observation.h"
#include "ui/views/widget/widget_observer.h"
// Tracks if a given widget has been destroyed.
class WidgetDestructionObserver : public views::WidgetObserver {
public:
explicit WidgetDestructionObserver(views::Widget* widget) : widget_(widget) {
DCHECK(widget);
observation_.Observe(widget);
}
WidgetDestructionObserver(const WidgetDestructionObserver&) = delete;
WidgetDestructionObserver& operator=(const WidgetDestructionObserver&) =
delete;
~WidgetDestructionObserver() override = default;
// views::WidgetObserver:
void OnWidgetDestroyed(views::Widget* widget) override {
DCHECK(widget_);
widget_ = nullptr;
observation_.Reset();
}
views::Widget* widget() const { return widget_; }
private:
views::Widget* widget_;
base::ScopedObservation<views::Widget, views::WidgetObserver> observation_{
this};
};

View File

@@ -6,6 +6,7 @@
#include "libcef/browser/browser_util.h"
#include "libcef/browser/thread_util.h"
#include "libcef/browser/views/browser_view_impl.h"
#include "libcef/browser/views/display_impl.h"
#include "libcef/browser/views/fill_layout_impl.h"
#include "libcef/browser/views/layout_util.h"
@@ -13,11 +14,13 @@
#include "libcef/browser/views/window_view.h"
#include "base/i18n/rtl.h"
#include "components/constrained_window/constrained_window_views.h"
#include "ui/base/test/ui_controls.h"
#include "ui/compositor/compositor.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/webview/webview.h"
#if defined(USE_AURA)
#include "ui/aura/window.h"
@@ -122,10 +125,38 @@ CefRefPtr<CefWindowImpl> CefWindowImpl::Create(
void CefWindowImpl::Show() {
CEF_REQUIRE_VALID_RETURN_VOID();
if (widget_) {
shown_as_browser_modal_ = false;
widget_->Show();
}
}
void CefWindowImpl::ShowAsBrowserModalDialog(
CefRefPtr<CefBrowserView> browser_view) {
CEF_REQUIRE_VALID_RETURN_VOID();
if (widget_) {
auto* browser_view_impl =
static_cast<CefBrowserViewImpl*>(browser_view.get());
// |browser_view| must belong to the host widget.
auto* host_widget = static_cast<CefWindowView*>(root_view())->host_widget();
CHECK(host_widget &&
browser_view_impl->root_view()->GetWidget() == host_widget);
if (auto web_view = browser_view_impl->web_view()) {
if (auto web_contents = web_view->web_contents()) {
shown_as_browser_modal_ = true;
constrained_window::ShowModalDialog(widget_->GetNativeWindow(),
web_contents);
// NativeWebContentsModalDialogManagerViews::ManageDialog() disables
// movement. That has no impact on native frames but interferes with
// draggable regions.
widget_->set_movement_disabled(false);
}
}
}
}
void CefWindowImpl::Hide() {
CEF_REQUIRE_VALID_RETURN_VOID();
if (widget_) {
@@ -403,6 +434,11 @@ void CefWindowImpl::SetBackgroundColor(cef_color_t color) {
}
bool CefWindowImpl::CanWidgetClose() {
if (shown_as_browser_modal_) {
// Always allow the close for browser modal dialogs to avoid an infinite
// loop in WebContentsModalDialogManager::CloseAllDialogs().
return true;
}
if (delegate()) {
return delegate()->CanClose(this);
}

View File

@@ -40,6 +40,8 @@ class CefWindowImpl
// CefWindow methods:
void Show() override;
void ShowAsBrowserModalDialog(
CefRefPtr<CefBrowserView> browser_view) override;
void Hide() override;
void CenterWindow(const CefSize& size) override;
void Close() override;
@@ -162,6 +164,9 @@ class CefWindowImpl
std::unique_ptr<ui::EventHandler> unhandled_key_event_handler_;
#endif
// True if this window was shown using ShowAsBrowserModalDialog().
bool shown_as_browser_modal_ = false;
IMPLEMENT_REFCOUNTING_DELETE_ON_UIT(CefWindowImpl);
};

View File

@@ -11,6 +11,7 @@
#include "libcef/features/runtime.h"
#include "ui/base/hit_test.h"
#include "ui/display/screen.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/native_frame_view.h"
@@ -18,11 +19,20 @@
#include "ui/ozone/buildflags.h"
#if BUILDFLAG(OZONE_PLATFORM_X11)
#include "ui/base/x/x11_util.h"
#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/gfx/x/xproto_util.h"
#include "ui/linux/linux_ui_delegate.h"
#endif
#endif
#if BUILDFLAG(IS_OZONE)
#include "ui/ozone/public/ozone_platform.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "ui/display/screen.h"
#include <dwmapi.h>
#include "base/win/windows_version.h"
#include "ui/display/win/screen_win.h"
#include "ui/views/win/hwnd_util.h"
#endif
@@ -67,17 +77,47 @@ class NativeFrameViewEx : public views::NativeFrameView {
gfx::Rect GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const override {
#if BUILDFLAG(IS_WIN)
// views::GetWindowBoundsForClientBounds() expects the input Rect to be in
// pixel coordinates. NativeFrameView does not implement this correctly so
// we need to provide our own implementation. See http://crbug.com/602692.
gfx::Rect pixel_bounds =
display::Screen::GetScreen()->DIPToScreenRectInWindow(
view_util::GetNativeWindow(widget_), client_bounds);
pixel_bounds = views::GetWindowBoundsForClientBounds(
static_cast<View*>(const_cast<NativeFrameViewEx*>(this)), pixel_bounds);
return display::Screen::GetScreen()->ScreenToDIPRectInWindow(
view_util::GetNativeWindow(widget_), pixel_bounds);
#if BUILDFLAG(IS_MAC)
// From NativeFrameView::GetWindowBoundsForClientBounds:
gfx::Rect window_bounds = client_bounds;
// Enforce minimum size (1, 1) in case that |client_bounds| is passed with
// empty size.
if (window_bounds.IsEmpty()) {
window_bounds.set_size(gfx::Size(1, 1));
}
if (!view_->IsFrameless()) {
if (auto titlebar_height = view_->GetTitlebarHeight()) {
window_bounds.Inset(gfx::Insets::TLBR(-(*titlebar_height), 0, 0, 0));
}
}
return window_bounds;
#elif BUILDFLAG(IS_WIN)
HWND window = views::HWNDForWidget(widget_);
CHECK(window);
const DWORD style = GetWindowLong(window, GWL_STYLE);
const DWORD ex_style = GetWindowLong(window, GWL_EXSTYLE);
const bool has_menu = !(style & WS_CHILD) && (GetMenu(window) != NULL);
// Convert from DIP to pixel coordinates using a method that can handle
// multiple displays with different DPI.
const auto screen_rect =
display::win::ScreenWin::DIPToScreenRect(window, client_bounds);
RECT rect = {screen_rect.x(), screen_rect.y(),
screen_rect.x() + screen_rect.width(),
screen_rect.y() + screen_rect.height()};
AdjustWindowRectEx(&rect, style, has_menu, ex_style);
// Keep the original origin while potentially increasing the size to include
// the frame non-client area.
gfx::Rect pixel_rect(screen_rect.x(), screen_rect.y(),
rect.right - rect.left, rect.bottom - rect.top);
// Convert back to DIP.
return display::win::ScreenWin::ScreenToDIPRect(window, pixel_rect);
#else
// Use the default implementation.
return views::NativeFrameView::GetWindowBoundsForClientBounds(
@@ -99,6 +139,25 @@ class NativeFrameViewEx : public views::NativeFrameView {
return views::NativeFrameView::NonClientHitTest(point);
}
#if BUILDFLAG(IS_WIN)
void OnThemeChanged() override {
views::NativeFrameView::OnThemeChanged();
// Value was 19 prior to Windows 10 20H1, according to
// https://stackoverflow.com/a/70693198
const DWORD dwAttribute =
base::win::GetVersion() >= base::win::Version::WIN10_20H1
? DWMWA_USE_IMMERSIVE_DARK_MODE
: 19;
// From BrowserFrameViewWin::SetSystemMicaTitlebarAttributes:
const BOOL dark_titlebar_enabled = GetNativeTheme()->ShouldUseDarkColors();
DwmSetWindowAttribute(views::HWNDForWidget(widget_), dwAttribute,
&dark_titlebar_enabled,
sizeof(dark_titlebar_enabled));
}
#endif
private:
// Not owned by this object.
views::Widget* widget_;
@@ -253,13 +312,62 @@ bool IsWindowBorderHit(int code) {
#endif
}
// Based on UpdateModalDialogPosition() from
// components/constrained_window/constrained_window_views.cc
void UpdateModalDialogPosition(views::Widget* widget,
views::Widget* host_widget) {
// Do not forcibly update the dialog widget position if it is being dragged.
if (widget->HasCapture()) {
return;
}
const gfx::Size& size = widget->GetRootView()->GetPreferredSize();
const gfx::Size& host_size =
host_widget->GetClientAreaBoundsInScreen().size();
// Center the dialog. Position is relative to the host.
gfx::Point position;
position.set_x((host_size.width() - size.width()) / 2);
position.set_y((host_size.height() - size.height()) / 2);
// Align the first row of pixels inside the border. This is the apparent top
// of the dialog.
position.set_y(position.y() -
widget->non_client_view()->frame_view()->GetInsets().top());
const bool supports_global_screen_coordinates =
#if !BUILDFLAG(IS_OZONE)
true;
#else
ui::OzonePlatform::GetInstance()
->GetPlatformProperties()
.supports_global_screen_coordinates;
#endif
if (widget->is_top_level() && supports_global_screen_coordinates) {
position += host_widget->GetClientAreaBoundsInScreen().OffsetFromOrigin();
// If the dialog extends partially off any display, clamp its position to
// be fully visible within that display. If the dialog doesn't intersect
// with any display clamp its position to be fully on the nearest display.
gfx::Rect display_rect = gfx::Rect(position, size);
const display::Display display =
display::Screen::GetScreen()->GetDisplayNearestView(
view_util::GetNativeView(host_widget));
const gfx::Rect work_area = display.work_area();
if (!work_area.Contains(display_rect)) {
display_rect.AdjustToFit(work_area);
}
position = display_rect.origin();
}
widget->SetBounds(gfx::Rect(position, size));
}
} // namespace
CefWindowView::CefWindowView(CefWindowDelegate* cef_delegate,
Delegate* window_delegate)
: ParentClass(cef_delegate),
window_delegate_(window_delegate),
is_frameless_(false) {
: ParentClass(cef_delegate), window_delegate_(window_delegate) {
DCHECK(window_delegate_);
}
@@ -274,6 +382,8 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
views::Widget::InitParams params;
params.delegate = this;
views::Widget* host_widget = nullptr;
bool can_activate = true;
bool can_resize = true;
@@ -343,6 +453,12 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
CefWindowImpl* parent_window_impl =
static_cast<CefWindowImpl*>(parent_window.get());
params.parent = view_util::GetNativeView(parent_window_impl->widget());
// Aura uses the same types for NativeView and NativeWindow, which can
// be confusing. Verify that we set |params.parent| correctly (to the
// expected internal::NativeWidgetPrivate) for Widget::Init usage.
DCHECK(views::Widget::GetWidgetForNativeView(params.parent));
if (is_menu) {
// Don't clip the window to parent bounds.
params.type = views::Widget::InitParams::TYPE_MENU;
@@ -351,6 +467,24 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
params.z_order = ui::ZOrderLevel::kNormal;
can_activate = can_activate_menu;
} else {
// Create a top-level window that is moveable and can exceed the
// bounds of the parent window. By not setting |params.child| here we
// cause OnBeforeWidgetInit to create a views::DesktopNativeWidgetAura
// instead of a views::NativeWidgetAura. We need to use this desktop
// variant with browser windows to get proper focus and shutdown
// behavior.
#if !BUILDFLAG(IS_LINUX)
// SetModalType doesn't work on Linux (no implementation in
// DesktopWindowTreeHostLinux::InitModalType). See the X11-specific
// implementation below that may work with some window managers.
if (cef_delegate()->IsWindowModalDialog(cef_window)) {
SetModalType(ui::MODAL_TYPE_WINDOW);
}
#endif
host_widget = parent_window_impl->widget();
}
}
}
@@ -395,13 +529,53 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
#if BUILDFLAG(IS_LINUX)
#if BUILDFLAG(OZONE_PLATFORM_X11)
auto x11window = static_cast<x11::Window>(view_util::GetWindowHandle(widget));
CHECK(x11window != x11::Window::None);
if (is_frameless_) {
auto window = view_util::GetWindowHandle(widget);
DCHECK(window);
ui::SetUseOSWindowFrame(static_cast<x11::Window>(window), false);
ui::SetUseOSWindowFrame(x11window, false);
}
if (host_widget) {
auto parent = static_cast<gfx::AcceleratedWidget>(
view_util::GetWindowHandle(host_widget));
CHECK(parent);
if (cef_delegate() && cef_delegate()->IsWindowModalDialog(GetCefWindow())) {
// The presence of _NET_WM_STATE_MODAL in _NET_SUPPORTED indicates
// possible window manager support. However, some window managers still
// don't support this properly.
x11::Atom modal_atom = x11::GetAtom("_NET_WM_STATE_MODAL");
if (ui::WmSupportsHint(modal_atom)) {
ui::SetWMSpecState(x11window, true, modal_atom, x11::Atom::None);
} else {
LOG(ERROR)
<< "Window modal dialogs are not supported by the window manager";
}
}
// From GtkUiPlatformX11::SetGtkWidgetTransientFor:
x11::SetProperty(x11window, x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW,
parent);
x11::SetProperty(x11window, x11::GetAtom("_NET_WM_WINDOW_TYPE"),
x11::Atom::ATOM,
x11::GetAtom("_NET_WM_WINDOW_TYPE_DIALOG"));
ui::LinuxUiDelegate::GetInstance()->SetTransientWindowForParent(
parent, static_cast<gfx::AcceleratedWidget>(x11window));
}
#endif
#endif
if (host_widget) {
// Position |widget| relative to |host_widget|.
UpdateModalDialogPosition(widget, host_widget);
// Track the lifespan of |host_widget|, which may be destroyed before
// |widget|.
host_widget_destruction_observer_ =
std::make_unique<WidgetDestructionObserver>(host_widget);
}
}
CefRefPtr<CefWindow> CefWindowView::GetCefWindow() const {
@@ -457,6 +631,20 @@ ui::ImageModel CefWindowView::GetWindowAppIcon() {
}
void CefWindowView::WindowClosing() {
#if BUILDFLAG(IS_LINUX)
#if BUILDFLAG(OZONE_PLATFORM_X11)
if (host_widget()) {
auto parent = static_cast<gfx::AcceleratedWidget>(
view_util::GetWindowHandle(host_widget()));
CHECK(parent);
// From GtkUiPlatformX11::ClearTransientFor:
ui::LinuxUiDelegate::GetInstance()->SetTransientWindowForParent(
parent, static_cast<gfx::AcceleratedWidget>(x11::Window::None));
}
#endif
#endif
window_delegate_->OnWindowClosing();
}
@@ -704,6 +892,13 @@ void CefWindowView::UpdateFindBarBoundingBox(gfx::Rect* bounds) const {
}
}
views::Widget* CefWindowView::host_widget() const {
if (host_widget_destruction_observer_) {
return host_widget_destruction_observer_->widget();
}
return nullptr;
}
absl::optional<float> CefWindowView::GetTitlebarHeight() const {
if (cef_delegate()) {
float title_bar_height = 0;

View File

@@ -13,6 +13,7 @@
#include "libcef/browser/views/overlay_view_host.h"
#include "libcef/browser/views/panel_view.h"
#include "libcef/browser/views/widget_destruction_observer.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "ui/display/display.h"
@@ -116,19 +117,24 @@ class CefWindowView
// Optionally modify the bounding box for the Chrome Find bar.
void UpdateFindBarBoundingBox(gfx::Rect* bounds) const;
absl::optional<float> GetTitlebarHeight() const;
bool IsFrameless() const { return is_frameless_; }
// The Widget that hosts us, if we're a modal dialog. May return nullptr
// during initialization and destruction.
views::Widget* host_widget() const;
private:
// Called when removed from the Widget and before |this| is deleted.
void DeleteDelegate();
void MoveOverlaysIfNecessary();
absl::optional<float> GetTitlebarHeight() const;
// Not owned by this object.
Delegate* window_delegate_;
// True if the window is frameless. It might still be resizable and draggable.
bool is_frameless_;
bool is_frameless_ = false;
std::u16string title_;
CefRefPtr<CefImage> window_icon_;
@@ -137,6 +143,9 @@ class CefWindowView
std::unique_ptr<SkRegion> draggable_region_;
std::vector<gfx::Rect> draggable_rects_;
// Tracks the Widget that hosts us, if we're a modal dialog.
std::unique_ptr<WidgetDestructionObserver> host_widget_destruction_observer_;
// Hosts for overlay widgets.
std::vector<std::unique_ptr<CefOverlayViewHost>> overlay_hosts_;
};

View File

@@ -61,19 +61,19 @@ void ChromeMainRunnerDelegate::BeforeMainMessageLoopRun(
keep_alive_ = std::make_unique<ScopedKeepAlive>(
KeepAliveOrigin::APP_CONTROLLER, KeepAliveRestartOption::DISABLED);
// The idle callback will be executed from BrowserProcessImpl::Unpin() via
// The QuitClosure will be executed from BrowserProcessImpl::Unpin() via
// KeepAliveRegistry when the last ScopedKeepAlive is released.
// ScopedKeepAlives are also held by Browser objects.
DCHECK(g_browser_process);
static_cast<BrowserProcessImpl*>(g_browser_process)
->SetQuitClosure(run_loop->QuitWhenIdleClosure());
->SetQuitClosure(run_loop->QuitClosure());
}
bool ChromeMainRunnerDelegate::HandleMainMessageLoopQuit() {
// May be called multiple times. See comments in RunMainMessageLoopBefore.
keep_alive_.reset();
// Cancel direct execution of the QuitWhenIdleClosure() in
// Cancel direct execution of the QuitClosure() in
// CefMainRunner::QuitMessageLoop. We instead wait for all Chrome browser
// windows to exit.
return true;

View File

@@ -83,18 +83,12 @@ base::FilePath GetUserDataPath(CefSettings* settings,
const base::CommandLine* command_line) {
// |settings| will be non-nullptr in the main process only.
if (settings) {
// With the Chrome runtime Profile paths must always be relative to the
// user data directory, so defaulting to |root_cache_path| first is
// appropriate.
CefString user_data_path;
if (cef::IsChromeRuntimeEnabled() && settings->root_cache_path.length > 0) {
user_data_path = CefString(&settings->root_cache_path);
CefString root_cache_path;
if (settings->root_cache_path.length > 0) {
root_cache_path = CefString(&settings->root_cache_path);
}
if (user_data_path.empty() && settings->user_data_path.length > 0) {
user_data_path = CefString(&settings->user_data_path);
}
if (!user_data_path.empty()) {
return base::FilePath(user_data_path);
if (!root_cache_path.empty()) {
return base::FilePath(root_cache_path);
}
}

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=2f28922e536557bff211610dd38bb7b4c8a64d5a$
// $hash=23777aea864e9abf38c2e2c5d79a40d6bd22876d$
//
#include "libcef_dll/cpptoc/views/window_cpptoc.h"
@@ -66,6 +66,28 @@ void CEF_CALLBACK window_show(struct _cef_window_t* self) {
CefWindowCppToC::Get(self)->Show();
}
void CEF_CALLBACK
window_show_as_browser_modal_dialog(struct _cef_window_t* self,
cef_browser_view_t* browser_view) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self) {
return;
}
// Verify param: browser_view; type: refptr_same
DCHECK(browser_view);
if (!browser_view) {
return;
}
// Execute
CefWindowCppToC::Get(self)->ShowAsBrowserModalDialog(
CefBrowserViewCppToC::Unwrap(browser_view));
}
void CEF_CALLBACK window_hide(struct _cef_window_t* self) {
shutdown_checker::AssertNotShutdown();
@@ -1970,6 +1992,8 @@ int CEF_CALLBACK window_convert_point_from_view(struct _cef_view_t* self,
CefWindowCppToC::CefWindowCppToC() {
GetStruct()->show = window_show;
GetStruct()->show_as_browser_modal_dialog =
window_show_as_browser_modal_dialog;
GetStruct()->hide = window_hide;
GetStruct()->center_window = window_center_window;
GetStruct()->close = window_close;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=12ff3d7d14f9977ff1f62e9a35b04b153a135480$
// $hash=6700d328968cb5c0141cd2d93ce66835e97a9d66$
//
#ifndef CEF_LIBCEF_DLL_CPPTOC_VIEWS_WINDOW_CPPTOC_H_
@@ -20,7 +20,9 @@
#error This file can be included DLL-side only
#endif
#include "include/capi/views/cef_browser_view_capi.h"
#include "include/capi/views/cef_window_capi.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "libcef_dll/cpptoc/cpptoc_ref_counted.h"

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=c84eb9772fc902904ccbd0cebe2c2105d06a8164$
// $hash=10ec416d3aeba7215b08604b1a329adc1c9aaf6f$
//
#include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h"
@@ -194,6 +194,31 @@ window_delegate_get_parent_window(struct _cef_window_delegate_t* self,
return CefWindowCToCpp::Unwrap(_retval);
}
int CEF_CALLBACK
window_delegate_is_window_modal_dialog(struct _cef_window_delegate_t* self,
cef_window_t* window) {
shutdown_checker::AssertNotShutdown();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self) {
return 0;
}
// Verify param: window; type: refptr_diff
DCHECK(window);
if (!window) {
return 0;
}
// Execute
bool _retval = CefWindowDelegateCppToC::Get(self)->IsWindowModalDialog(
CefWindowCToCpp::Wrap(window));
// Return type: bool
return _retval;
}
cef_rect_t CEF_CALLBACK
window_delegate_get_initial_bounds(struct _cef_window_delegate_t* self,
cef_window_t* window) {
@@ -781,6 +806,7 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() {
GetStruct()->on_window_bounds_changed =
window_delegate_on_window_bounds_changed;
GetStruct()->get_parent_window = window_delegate_get_parent_window;
GetStruct()->is_window_modal_dialog = window_delegate_is_window_modal_dialog;
GetStruct()->get_initial_bounds = window_delegate_get_initial_bounds;
GetStruct()->get_initial_show_state = window_delegate_get_initial_show_state;
GetStruct()->is_frameless = window_delegate_is_frameless;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=29399b84620b09e086f65f712b50573d7fcd1be8$
// $hash=b6b0a2a563b475163aa71b20af6ec2ac8c1f0cae$
//
#include "libcef_dll/ctocpp/views/window_ctocpp.h"
@@ -65,6 +65,29 @@ NO_SANITIZE("cfi-icall") void CefWindowCToCpp::Show() {
_struct->show(_struct);
}
NO_SANITIZE("cfi-icall")
void CefWindowCToCpp::ShowAsBrowserModalDialog(
CefRefPtr<CefBrowserView> browser_view) {
shutdown_checker::AssertNotShutdown();
cef_window_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, show_as_browser_modal_dialog)) {
return;
}
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: browser_view; type: refptr_same
DCHECK(browser_view.get());
if (!browser_view.get()) {
return;
}
// Execute
_struct->show_as_browser_modal_dialog(
_struct, CefBrowserViewCToCpp::Unwrap(browser_view));
}
NO_SANITIZE("cfi-icall") void CefWindowCToCpp::Hide() {
shutdown_checker::AssertNotShutdown();

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=5ea05d2b5c24bfc214a529d62fba2e69ea626b78$
// $hash=2a7aaed7d4296e29dca74345cf2b2d4db221a738$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_
@@ -21,7 +21,9 @@
#endif
#include <vector>
#include "include/capi/views/cef_browser_view_capi.h"
#include "include/capi/views/cef_window_capi.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "libcef_dll/ctocpp/ctocpp_ref_counted.h"
@@ -35,6 +37,8 @@ class CefWindowCToCpp
// CefWindow methods.
void Show() override;
void ShowAsBrowserModalDialog(
CefRefPtr<CefBrowserView> browser_view) override;
void Hide() override;
void CenterWindow(const CefSize& size) override;
void Close() override;

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=8998830c31f54e6e1199390c42a912033dabd6ad$
// $hash=12bd03a8fb7d680a4e2b1a6818313c29bf14f011$
//
#include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h"
@@ -182,6 +182,31 @@ CefRefPtr<CefWindow> CefWindowDelegateCToCpp::GetParentWindow(
return CefWindowCppToC::Unwrap(_retval);
}
NO_SANITIZE("cfi-icall")
bool CefWindowDelegateCToCpp::IsWindowModalDialog(CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown();
cef_window_delegate_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, is_window_modal_dialog)) {
return false;
}
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: window; type: refptr_diff
DCHECK(window.get());
if (!window.get()) {
return false;
}
// Execute
int _retval =
_struct->is_window_modal_dialog(_struct, CefWindowCppToC::Wrap(window));
// Return type: bool
return _retval ? true : false;
}
NO_SANITIZE("cfi-icall")
CefRect CefWindowDelegateCToCpp::GetInitialBounds(CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown();

View File

@@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=bf87c473a5bafd3f8c30bd06c033b0182f65a7b7$
// $hash=25487f4d82069d1e4c0c7b27c1c1fcbcebbbacea$
//
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_
@@ -47,6 +47,7 @@ class CefWindowDelegateCToCpp
CefRefPtr<CefWindow> GetParentWindow(CefRefPtr<CefWindow> window,
bool* is_menu,
bool* can_activate_menu) override;
bool IsWindowModalDialog(CefRefPtr<CefWindow> window) override;
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
cef_show_state_t GetInitialShowState(CefRefPtr<CefWindow> window) override;
bool IsFrameless(CefRefPtr<CefWindow> window) override;

View File

@@ -243,6 +243,9 @@ patches = [
# - Support nullptr gfx::NativeWindow/gfx::NativeView dialog parent for CEF
# windowless rendering.
# https://github.com/chromiumembedded/cef/issues/3316
#
# Fix NativeWebContentsModalDialogManagerViews::HostChanged to not reparent
# between different root windows.
'name': 'chrome_browser_dialogs_widget',
},
{
@@ -627,5 +630,19 @@ patches = [
# macOS: Remove run-time dependency on libtest_trace_processor.dylib
# Reverts the changes from https://crrev.com/8b18bd125d
'name': 'base_test_4396276'
},
{
# Create top-level widget type when Widget::InitParams::child is false.
'name': 'ui_views_widget_type'
},
{
# win/linux: Fix rounding errors with Screen[Win] DIP/pixel conversions.
# https://bugs.chromium.org/p/chromium/issues/detail?id=1443650#c18
'name': 'screen_1443650'
},
{
# mac: Keep bubble popups on-screen.
# https://bugs.chromium.org/p/chromium/issues/detail?id=893292#c10
'name': 'mac_platform_style_bubble_893292'
}
]

View File

@@ -20,10 +20,10 @@ index 38f318f9c0b45..0c8c86efedd07 100644
// Make an exception to allow most visited tiles to commit in
diff --git content/browser/renderer_host/navigation_request.cc content/browser/renderer_host/navigation_request.cc
index ad258abf7e17f..4d94f7144f5ce 100644
index 26ac68abf3333..a318d55fa1698 100644
--- content/browser/renderer_host/navigation_request.cc
+++ content/browser/renderer_host/navigation_request.cc
@@ -7446,10 +7446,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
@@ -7479,10 +7479,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
bool use_opaque_origin =
(sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) ==
network::mojom::WebSandboxFlags::kOrigin;
@@ -47,7 +47,7 @@ index ad258abf7e17f..4d94f7144f5ce 100644
}
return origin_and_debug_info;
@@ -7479,6 +7491,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
@@ -7512,6 +7524,15 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
SandboxFlagsToCommit());

View File

@@ -13,10 +13,10 @@ index 9d9c17ffd6474..4eb79c65369af 100644
};
diff --git content/public/browser/webui_config_map.h content/public/browser/webui_config_map.h
index 19777632921fc..a22db4c49fd84 100644
index a80034506bf45..4bda477df0558 100644
--- content/public/browser/webui_config_map.h
+++ content/public/browser/webui_config_map.h
@@ -60,6 +60,10 @@ class CONTENT_EXPORT WebUIConfigMap {
@@ -61,6 +61,10 @@ class CONTENT_EXPORT WebUIConfigMap {
// Returns the size of the map, i.e. how many WebUIConfigs are registered.
size_t GetSizeForTesting() { return configs_map_.size(); }

View File

@@ -13,7 +13,7 @@ index 2480282a19d12..dbd1fbf8a15b5 100644
return false;
}
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
index 9e536d6f48970..aeb659d55123c 100644
index 7a0b2dd74a3be..370dc999ebe4f 100644
--- chrome/browser/ui/BUILD.gn
+++ chrome/browser/ui/BUILD.gn
@@ -9,6 +9,7 @@ import("//build/config/compiler/compiler.gni")
@@ -52,7 +52,7 @@ index 9e536d6f48970..aeb659d55123c 100644
"views/apps/app_info_dialog/arc_app_info_links_panel.cc",
"views/apps/app_info_dialog/arc_app_info_links_panel.h",
"views/apps/chrome_app_window_client_views_chromeos.cc",
@@ -4499,8 +4507,6 @@ static_library("ui") {
@@ -4501,8 +4509,6 @@ static_library("ui") {
"views/accessibility/theme_tracking_non_accessible_image_view.h",
"views/apps/app_dialog/app_dialog_view.cc",
"views/apps/app_dialog/app_dialog_view.h",
@@ -61,7 +61,7 @@ index 9e536d6f48970..aeb659d55123c 100644
"views/apps/app_info_dialog/app_info_dialog_container.cc",
"views/apps/app_info_dialog/app_info_dialog_container.h",
"views/apps/app_info_dialog/app_info_dialog_views.cc",
@@ -6082,6 +6088,7 @@ static_library("ui") {
@@ -6086,6 +6092,7 @@ static_library("ui") {
if (enable_printing) {
deps += [
"//components/printing/browser",
@@ -410,10 +410,10 @@ index 23a838ba30c68..52601ebdcc9bd 100644
// The opener browser of the document picture-in-picture browser. Null if the
diff --git chrome/browser/ui/browser_navigator.cc chrome/browser/ui/browser_navigator.cc
index edf4d8c7933e9..9e7c236dbf16a 100644
index a45328dab1538..981e8e498752b 100644
--- chrome/browser/ui/browser_navigator.cc
+++ chrome/browser/ui/browser_navigator.cc
@@ -555,6 +555,13 @@ std::unique_ptr<content::WebContents> CreateTargetContents(
@@ -556,6 +556,13 @@ std::unique_ptr<content::WebContents> CreateTargetContents(
std::unique_ptr<WebContents> target_contents =
WebContents::Create(create_params);

View File

@@ -1,8 +1,8 @@
diff --git chrome/browser/renderer_context_menu/render_view_context_menu.cc chrome/browser/renderer_context_menu/render_view_context_menu.cc
index 7e25c4f0656fa..446075c9dfaf7 100644
index 216e16410ba43..fabdee75267a3 100644
--- chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -322,6 +322,13 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
@@ -324,6 +324,13 @@ base::OnceCallback<void(RenderViewContextMenu*)>* GetMenuShownCallback() {
return callback.get();
}
@@ -16,7 +16,7 @@ index 7e25c4f0656fa..446075c9dfaf7 100644
enum class UmaEnumIdLookupType {
GeneralEnumId,
ContextSpecificEnumId,
@@ -568,6 +575,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
@@ -570,6 +577,10 @@ int FindUMAEnumValueForCommand(int id, UmaEnumIdLookupType type) {
if (ContextMenuMatcher::IsExtensionsCustomCommandId(id))
return 1;
@@ -27,7 +27,7 @@ index 7e25c4f0656fa..446075c9dfaf7 100644
id = CollapseCommandsForUMA(id);
const auto& map = GetIdcToUmaMap(type);
auto it = map.find(id);
@@ -808,6 +819,14 @@ RenderViewContextMenu::RenderViewContextMenu(
@@ -810,6 +821,14 @@ RenderViewContextMenu::RenderViewContextMenu(
#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
pdf_ocr_submenu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
@@ -42,10 +42,10 @@ index 7e25c4f0656fa..446075c9dfaf7 100644
}
RenderViewContextMenu::~RenderViewContextMenu() = default;
@@ -1229,6 +1248,12 @@ void RenderViewContextMenu::InitMenu() {
// menu, meaning that each menu item added/removed in this function will cause
// it to visibly jump on the screen (see b/173569669).
AppendQuickAnswersItems();
@@ -1244,6 +1263,12 @@ void RenderViewContextMenu::InitMenu() {
autofill::PopupHidingReason::kContextMenuOpened);
}
}
+
+ if (first_observer_) {
+ // Do this last so that the observer can optionally modify previously
@@ -55,7 +55,7 @@ index 7e25c4f0656fa..446075c9dfaf7 100644
}
Profile* RenderViewContextMenu::GetProfile() const {
@@ -3224,6 +3249,12 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
@@ -3239,6 +3264,12 @@ void RenderViewContextMenu::RegisterExecutePluginActionCallbackForTesting(
execute_plugin_action_callback_ = std::move(cb);
}

View File

@@ -77,10 +77,10 @@ index dc648ad1ae595..70698ed848990 100644
DCHECK_EQ(parent_view, host->GetHostView());
ModalDialogHostObserver* dialog_host_observer =
diff --git components/constrained_window/native_web_contents_modal_dialog_manager_views.cc components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
index 647391095306e..02aea9b01f59b 100644
index 647391095306e..bd49316ac758e 100644
--- components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
+++ components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
@@ -184,9 +184,12 @@ void NativeWebContentsModalDialogManagerViews::HostChanged(
@@ -184,9 +184,20 @@ void NativeWebContentsModalDialogManagerViews::HostChanged(
if (host_) {
host_->AddObserver(this);
@@ -90,8 +90,16 @@ index 647391095306e..02aea9b01f59b 100644
+ // |host_view| will be nullptr with CEF windowless rendering.
+ if (auto host_view = host_->GetHostView()) {
+ for (auto* widget : observed_widgets_) {
+ views::Widget::ReparentNativeView(widget->GetNativeView(),
+ host_view);
+#if defined(USE_AURA)
+ auto widget_view = widget->GetNativeView();
+ // Don't reparent between different root windows. Doing so causes
+ // issues with layout of dialogs containing Chrome browsers.
+ if (host_view->GetRootWindow() == widget_view->GetRootWindow()) {
+ views::Widget::ReparentNativeView(widget_view, host_view);
+ }
+#else
+ views::Widget::ReparentNativeView(widget->GetNativeView(), host_view);
+#endif
+ }
}

View File

@@ -44,7 +44,7 @@ index 16107572d4d0d..409e9ea870482 100644
base::FeatureList::IsEnabled(
features::kPeriodicSyncPermissionForDefaultSearchEngine) &&
diff --git chrome/browser/permissions/chrome_permissions_client.cc chrome/browser/permissions/chrome_permissions_client.cc
index dece5822d8899..855ab4273e916 100644
index 18e2eec8f64ff..d36b3206aeb63 100644
--- chrome/browser/permissions/chrome_permissions_client.cc
+++ chrome/browser/permissions/chrome_permissions_client.cc
@@ -14,6 +14,7 @@
@@ -65,7 +65,7 @@ index dece5822d8899..855ab4273e916 100644
return site_engagement::SiteEngagementService::Get(
Profile::FromBrowserContext(browser_context))
->GetScore(origin);
@@ -332,8 +336,10 @@ ChromePermissionsClient::CreatePermissionUiSelectors(
@@ -338,8 +342,10 @@ ChromePermissionsClient::CreatePermissionUiSelectors(
std::make_unique<ContextualNotificationPermissionUiSelector>());
selectors.emplace_back(std::make_unique<PrefNotificationPermissionUiSelector>(
Profile::FromBrowserContext(browser_context)));

View File

@@ -99,7 +99,7 @@ index a3ee1846fcf77..13edaf1203d69 100644
return raw_otr_profile;
}
diff --git chrome/browser/profiles/profile_manager.cc chrome/browser/profiles/profile_manager.cc
index 80acbb1473fc7..9db21208f8e81 100644
index 9eb766c7a5818..3a66b90b55dd6 100644
--- chrome/browser/profiles/profile_manager.cc
+++ chrome/browser/profiles/profile_manager.cc
@@ -389,7 +389,7 @@ ProfileManager::ProfileManager(const base::FilePath& user_data_dir)
@@ -112,7 +112,7 @@ index 80acbb1473fc7..9db21208f8e81 100644
zombie_metrics_timer_.Start(FROM_HERE, base::Minutes(30), this,
diff --git chrome/browser/profiles/profile_manager.h chrome/browser/profiles/profile_manager.h
index 60c9fd19fe15b..2a3e317d9c240 100644
index 9bb7cd968c95d..bf16634f7dfe8 100644
--- chrome/browser/profiles/profile_manager.h
+++ chrome/browser/profiles/profile_manager.h
@@ -130,7 +130,7 @@ class ProfileManager : public Profile::Delegate {

View File

@@ -235,7 +235,7 @@ index 789d147f0b305..64a33cce013c5 100644
+#endif
}
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc
index 1b9db89f8dce3..980999042366a 100644
index f5c614464662c..1a273805c05eb 100644
--- chrome/browser/chrome_content_browser_client.cc
+++ chrome/browser/chrome_content_browser_client.cc
@@ -41,6 +41,7 @@
@@ -279,7 +279,7 @@ index 1b9db89f8dce3..980999042366a 100644
}
base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
@@ -6229,7 +6239,7 @@ void ChromeContentBrowserClient::OnNetworkServiceCreated(
@@ -6230,7 +6240,7 @@ void ChromeContentBrowserClient::OnNetworkServiceCreated(
#endif
}
@@ -288,7 +288,7 @@ index 1b9db89f8dce3..980999042366a 100644
content::BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path,
@@ -6247,6 +6257,8 @@ void ChromeContentBrowserClient::ConfigureNetworkContextParams(
@@ -6248,6 +6258,8 @@ void ChromeContentBrowserClient::ConfigureNetworkContextParams(
network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
network_context_params->accept_language = GetApplicationLocale();
}
@@ -297,7 +297,7 @@ index 1b9db89f8dce3..980999042366a 100644
}
std::vector<base::FilePath>
@@ -7260,10 +7272,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
@@ -7274,10 +7286,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
const auto now = base::TimeTicks::Now();
const auto timeout = GetKeepaliveTimerTimeout(context);
keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
@@ -310,7 +310,7 @@ index 1b9db89f8dce3..980999042366a 100644
FROM_HERE, keepalive_deadline_ - now,
base::BindOnce(
&ChromeContentBrowserClient::OnKeepaliveTimerFired,
@@ -7282,7 +7294,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
@@ -7296,7 +7308,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
--num_keepalive_requests_;
if (num_keepalive_requests_ == 0) {
DVLOG(1) << "Stopping the keepalive timer";
@@ -320,7 +320,7 @@ index 1b9db89f8dce3..980999042366a 100644
// This deletes the keep alive handle attached to the timer function and
// unblock the shutdown sequence.
}
@@ -7418,7 +7431,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
@@ -7432,7 +7445,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
const auto now = base::TimeTicks::Now();
const auto then = keepalive_deadline_;
if (now < then) {
@@ -330,7 +330,7 @@ index 1b9db89f8dce3..980999042366a 100644
base::BindOnce(&ChromeContentBrowserClient::OnKeepaliveTimerFired,
weak_factory_.GetWeakPtr(),
diff --git chrome/browser/chrome_content_browser_client.h chrome/browser/chrome_content_browser_client.h
index 902dcaf5df1ca..d8e698886df54 100644
index 24b19245f3704..6ace7bc34a53e 100644
--- chrome/browser/chrome_content_browser_client.h
+++ chrome/browser/chrome_content_browser_client.h
@@ -135,6 +135,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
@@ -351,7 +351,7 @@ index 902dcaf5df1ca..d8e698886df54 100644
content::BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path,
@@ -1010,7 +1012,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
@@ -1013,7 +1015,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
#if !BUILDFLAG(IS_ANDROID)
uint64_t num_keepalive_requests_ = 0;

View File

@@ -1,8 +1,8 @@
diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc
index c1f28ebc372df..275657f54c517 100644
index 28088dd31e26b..e67e8164ed181 100644
--- chrome/browser/ui/browser_command_controller.cc
+++ chrome/browser/ui/browser_command_controller.cc
@@ -395,6 +395,7 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
@@ -406,6 +406,7 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
// choose to not implement CommandUpdaterDelegate inside this class and
// therefore command_updater_ doesn't have the delegate set).
if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
@@ -10,7 +10,7 @@ index c1f28ebc372df..275657f54c517 100644
return false;
}
@@ -411,6 +412,13 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
@@ -422,6 +423,13 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
DCHECK(command_updater_.IsCommandEnabled(id))
<< "Invalid/disabled command " << id;
@@ -24,7 +24,7 @@ index c1f28ebc372df..275657f54c517 100644
// The order of commands in this switch statement must match the function
// declaration order in browser.h!
switch (id) {
@@ -1102,11 +1110,13 @@ void BrowserCommandController::TabRestoreServiceLoaded(
@@ -1113,11 +1121,13 @@ void BrowserCommandController::TabRestoreServiceLoaded(
// BrowserCommandController, private:
bool BrowserCommandController::IsShowingMainUI() {
@@ -237,7 +237,7 @@ index 59024587ef6b7..0c30aa71768cf 100644
void FindBarHost::RegisterAccelerators() {
diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc
index 24b85357b90b8..67e1bacb8d518 100644
index e01f634cbe20f..9ece0073769e5 100644
--- chrome/browser/ui/views/frame/browser_frame.cc
+++ chrome/browser/ui/views/frame/browser_frame.cc
@@ -75,15 +75,23 @@ bool IsUsingLinuxSystemTheme(Profile* profile) {
@@ -347,7 +347,7 @@ index 24b85357b90b8..67e1bacb8d518 100644
#if BUILDFLAG(IS_CHROMEOS_ASH)
// ChromeOS SystemWebApps use the OS theme all the time.
if (ash::IsSystemWebApp(browser_view_->browser())) {
@@ -533,5 +566,8 @@ bool BrowserFrame::RegenerateFrameOnThemeChange(
@@ -540,5 +573,8 @@ bool BrowserFrame::RegenerateFrameOnThemeChange(
}
bool BrowserFrame::IsIncognitoBrowser() const {
@@ -371,7 +371,7 @@ index 795f057fedc51..54b08509919af 100644
BrowserFrame(const BrowserFrame&) = delete;
BrowserFrame& operator=(const BrowserFrame&) = delete;
diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
index 39a1660cae03a..f7d7965989cf7 100644
index bd940fc19123c..c31d4c8fb90fb 100644
--- chrome/browser/ui/views/frame/browser_view.cc
+++ chrome/browser/ui/views/frame/browser_view.cc
@@ -314,11 +314,10 @@ using content::NativeWebKeyboardEvent;
@@ -439,7 +439,24 @@ index 39a1660cae03a..f7d7965989cf7 100644
contents_separator_ =
top_container_->AddChildView(std::make_unique<ContentsSeparator>());
@@ -1817,6 +1833,8 @@ bool BrowserView::ShouldHideUIForFullscreen() const {
@@ -1082,12 +1098,14 @@ gfx::Size BrowserView::GetWebAppFrameToolbarPreferredSize() const {
#if BUILDFLAG(IS_MAC)
bool BrowserView::UsesImmersiveFullscreenMode() const {
+ if (!base::FeatureList::IsEnabled(features::kImmersiveFullscreen)) {
+ return false;
+ }
const bool is_pwa =
base::FeatureList::IsEnabled(features::kImmersiveFullscreenPWAs) &&
GetIsWebAppType();
const bool is_tabbed_window = GetSupportsTabStrip();
- return base::FeatureList::IsEnabled(features::kImmersiveFullscreen) &&
- (is_pwa || is_tabbed_window);
+ return is_pwa || is_tabbed_window;
}
bool BrowserView::UsesImmersiveFullscreenTabbedMode() const {
@@ -1812,6 +1830,8 @@ bool BrowserView::ShouldHideUIForFullscreen() const {
if (immersive_mode_controller_->IsEnabled())
return false;
@@ -448,7 +465,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
}
@@ -2722,7 +2740,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
@@ -2711,7 +2731,8 @@ DownloadShelf* BrowserView::GetDownloadShelf() {
}
DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() {
@@ -458,7 +475,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
if (auto* download_button = toolbar_button_provider_->GetDownloadButton())
return download_button->bubble_controller();
return nullptr;
@@ -3222,7 +3241,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
@@ -3211,7 +3232,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
if (top_container()->parent() == this)
return;
@@ -468,7 +485,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
top_container()->DestroyLayer();
AddChildViewAt(top_container(), 0);
EnsureFocusOrder();
@@ -3776,8 +3796,10 @@ void BrowserView::Layout() {
@@ -3765,8 +3787,10 @@ void BrowserView::Layout() {
// TODO(jamescook): Why was this in the middle of layout code?
toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
@@ -481,7 +498,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
// Some of the situations when the BrowserView is laid out are:
// - Enter/exit immersive fullscreen mode.
@@ -3843,6 +3865,11 @@ void BrowserView::AddedToWidget() {
@@ -3832,6 +3856,11 @@ void BrowserView::AddedToWidget() {
SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
#endif
@@ -493,7 +510,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
toolbar_->Init();
// TODO(pbos): Investigate whether the side panels should be creatable when
@@ -3889,13 +3916,9 @@ void BrowserView::AddedToWidget() {
@@ -3879,13 +3908,9 @@ void BrowserView::AddedToWidget() {
EnsureFocusOrder();
@@ -509,7 +526,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
using_native_frame_ = frame_->ShouldUseNativeFrame();
MaybeInitializeWebUITabStrip();
@@ -4300,7 +4323,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
@@ -4290,7 +4315,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
// Undo our anti-jankiness hacks and force a re-layout.
in_process_fullscreen_ = false;
ToolbarSizeChanged(false);
@@ -519,7 +536,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
}
bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const {
@@ -4671,6 +4695,8 @@ Profile* BrowserView::GetProfile() {
@@ -4661,6 +4687,8 @@ Profile* BrowserView::GetProfile() {
}
void BrowserView::UpdateUIForTabFullscreen() {
@@ -528,7 +545,7 @@ index 39a1660cae03a..f7d7965989cf7 100644
frame()->GetFrameView()->UpdateFullscreenTopUI();
}
@@ -4693,6 +4719,8 @@ void BrowserView::HideDownloadShelf() {
@@ -4683,6 +4711,8 @@ void BrowserView::HideDownloadShelf() {
}
bool BrowserView::CanUserExitFullscreen() const {
@@ -538,10 +555,10 @@ index 39a1660cae03a..f7d7965989cf7 100644
}
diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
index 3e812382f77e6..d821b03bfa510 100644
index b9bb37f29425c..4b36ea92a74a2 100644
--- chrome/browser/ui/views/frame/browser_view.h
+++ chrome/browser/ui/views/frame/browser_view.h
@@ -124,11 +124,16 @@ class BrowserView : public BrowserWindow,
@@ -123,11 +123,16 @@ class BrowserView : public BrowserWindow,
public webapps::AppBannerManager::Observer {
public:
METADATA_HEADER(BrowserView);
@@ -558,7 +575,7 @@ index 3e812382f77e6..d821b03bfa510 100644
void set_frame(BrowserFrame* frame) {
frame_ = frame;
paint_as_active_subscription_ =
@@ -783,6 +788,12 @@ class BrowserView : public BrowserWindow,
@@ -777,6 +782,12 @@ class BrowserView : public BrowserWindow,
return web_app_frame_toolbar();
}
@@ -686,10 +703,10 @@ index 2753a95f8ff35..9745477102917 100644
}
diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
index 4682fa0f74996..099742d04102a 100644
index 641236e5f8d88..03d55e77c1e31 100644
--- chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -175,12 +175,13 @@ constexpr int kBrowserAppMenuRefreshCollapsedMargin = 2;
@@ -176,12 +176,13 @@ constexpr int kBrowserAppMenuRefreshCollapsedMargin = 2;
////////////////////////////////////////////////////////////////////////////////
// ToolbarView, public:
@@ -705,7 +722,7 @@ index 4682fa0f74996..099742d04102a 100644
SetID(VIEW_ID_TOOLBAR);
if (display_mode_ == DisplayMode::NORMAL) {
@@ -202,6 +203,19 @@ ToolbarView::~ToolbarView() {
@@ -203,6 +204,19 @@ ToolbarView::~ToolbarView() {
}
void ToolbarView::Init() {
@@ -725,7 +742,7 @@ index 4682fa0f74996..099742d04102a 100644
#if defined(USE_AURA)
// Avoid generating too many occlusion tracking calculation events before this
// function returns. The occlusion status will be computed only once once this
@@ -211,12 +225,13 @@ void ToolbarView::Init() {
@@ -212,12 +226,13 @@ void ToolbarView::Init() {
#endif
auto location_bar = std::make_unique<LocationBarView>(
browser_, browser_->profile(), browser_->command_controller(), this,
@@ -741,7 +758,7 @@ index 4682fa0f74996..099742d04102a 100644
download_button =
std::make_unique<DownloadToolbarButtonView>(browser_view_);
}
@@ -297,8 +312,10 @@ void ToolbarView::Init() {
@@ -298,8 +313,10 @@ void ToolbarView::Init() {
}
}
std::unique_ptr<media_router::CastToolbarButton> cast;
@@ -753,7 +770,7 @@ index 4682fa0f74996..099742d04102a 100644
std::unique_ptr<MediaToolbarButtonView> media_button;
if (base::FeatureList::IsEnabled(media::kGlobalMediaControls)) {
@@ -308,7 +325,8 @@ void ToolbarView::Init() {
@@ -309,7 +326,8 @@ void ToolbarView::Init() {
std::unique_ptr<send_tab_to_self::SendTabToSelfToolbarIconView>
send_tab_to_self_button;
@@ -763,15 +780,15 @@ index 4682fa0f74996..099742d04102a 100644
send_tab_to_self_button =
std::make_unique<send_tab_to_self::SendTabToSelfToolbarIconView>(
browser_view_);
@@ -316,7 +334,7 @@ void ToolbarView::Init() {
@@ -317,7 +335,7 @@ void ToolbarView::Init() {
std::unique_ptr<SidePanelToolbarButton> side_panel_button;
std::unique_ptr<SidePanelToolbarContainer> side_panel_toolbar_container;
- if (browser_view_->unified_side_panel()) {
+ if (browser_view_->unified_side_panel() && BUTTON_VISIBLE(kSidePanel)) {
if (base::FeatureList::IsEnabled(
companion::features::kSidePanelCompanion)) {
if (companion::IsCompanionFeatureEnabled()) {
side_panel_toolbar_container =
std::make_unique<SidePanelToolbarContainer>(browser_view_);
diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
index c38f2b0545d21..fe9a92b2f610c 100644
--- chrome/browser/ui/views/toolbar/toolbar_view.h

View File

@@ -1,5 +1,5 @@
diff --git content/browser/devtools/devtools_instrumentation.h content/browser/devtools/devtools_instrumentation.h
index e36b1e99fb93d..1b7c458666cea 100644
index 540473243029e..fc5ae23c187d3 100644
--- content/browser/devtools/devtools_instrumentation.h
+++ content/browser/devtools/devtools_instrumentation.h
@@ -101,7 +101,7 @@ bool ApplyUserAgentMetadataOverrides(

View File

@@ -34,10 +34,10 @@ index 4438dea521489..987aa9714bd1c 100644
factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
std::move(loader_factory));
diff --git content/public/browser/content_browser_client.cc content/public/browser/content_browser_client.cc
index a5ea7baed1f09..8f3f679aed305 100644
index 139a3b1cbe854..cb26c1afd379a 100644
--- content/public/browser/content_browser_client.cc
+++ content/public/browser/content_browser_client.cc
@@ -986,7 +986,7 @@ ContentBrowserClient::CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
@@ -990,7 +990,7 @@ ContentBrowserClient::CreateURLLoaderHandlerForServiceWorkerNavigationPreload(
void ContentBrowserClient::OnNetworkServiceCreated(
network::mojom::NetworkService* network_service) {}
@@ -46,7 +46,7 @@ index a5ea7baed1f09..8f3f679aed305 100644
BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path,
@@ -995,6 +995,7 @@ void ContentBrowserClient::ConfigureNetworkContextParams(
@@ -999,6 +999,7 @@ void ContentBrowserClient::ConfigureNetworkContextParams(
cert_verifier_creation_params) {
network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
network_context_params->accept_language = "en-us,en";
@@ -55,7 +55,7 @@ index a5ea7baed1f09..8f3f679aed305 100644
std::vector<base::FilePath>
diff --git content/public/browser/content_browser_client.h content/public/browser/content_browser_client.h
index 3db43fde00af4..1be6b3926fcd3 100644
index 42805faf7e6cf..57c4e444ec126 100644
--- content/public/browser/content_browser_client.h
+++ content/public/browser/content_browser_client.h
@@ -37,6 +37,7 @@
@@ -66,7 +66,7 @@ index 3db43fde00af4..1be6b3926fcd3 100644
#include "content/public/common/alternative_error_page_override_info.mojom-forward.h"
#include "content/public/common/page_visibility_state.h"
#include "content/public/common/window_container_type.mojom-forward.h"
@@ -1815,7 +1816,7 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -1817,7 +1818,7 @@ class CONTENT_EXPORT ContentBrowserClient {
//
// If |relative_partition_path| is the empty string, it means this needs to
// create the default NetworkContext for the BrowserContext.
@@ -75,7 +75,7 @@ index 3db43fde00af4..1be6b3926fcd3 100644
BrowserContext* context,
bool in_memory,
const base::FilePath& relative_partition_path,
@@ -2023,6 +2024,19 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -2025,6 +2026,19 @@ class CONTENT_EXPORT ContentBrowserClient {
RenderFrameHost* initiator_document,
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory);
@@ -95,7 +95,7 @@ index 3db43fde00af4..1be6b3926fcd3 100644
// Creates an OverlayWindow to be used for video or Picture-in-Picture.
// This window will house the content shown when in Picture-in-Picture mode.
// This will return a new OverlayWindow.
@@ -2079,6 +2093,10 @@ class CONTENT_EXPORT ContentBrowserClient {
@@ -2081,6 +2095,10 @@ class CONTENT_EXPORT ContentBrowserClient {
// Used as part of the user agent string.
virtual std::string GetProduct();

View File

@@ -1,8 +1,8 @@
diff --git ui/accessibility/platform/BUILD.gn ui/accessibility/platform/BUILD.gn
index c9777e07fdd31..3858ce8c28cb3 100644
index 0e49fbdc2fb3e..d448b6bb32f5d 100644
--- ui/accessibility/platform/BUILD.gn
+++ ui/accessibility/platform/BUILD.gn
@@ -286,6 +286,10 @@ component("platform") {
@@ -287,6 +287,10 @@ component("platform") {
if (use_gio) {
configs += [ "//build/linux:gio_config" ]
}

View File

@@ -0,0 +1,28 @@
diff --git chrome/browser/ui/views/profiles/profile_menu_view_base.cc chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index 75402abc6c5c0..66bafe5d6186a 100644
--- chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -949,8 +949,8 @@ int ProfileMenuViewBase::GetMaxHeight() const {
->GetDisplayNearestPoint(anchor_rect.CenterPoint())
.work_area();
int available_space = screen_space.bottom() - anchor_rect.bottom();
-#if BUILDFLAG(IS_WIN)
- // On Windows the bubble can also be show to the top of the anchor.
+#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
+ // On Windows and macOS the bubble can also be show to the top of the anchor.
available_space =
std::max(available_space, anchor_rect.y() - screen_space.y());
#endif
diff --git ui/views/style/platform_style_mac.mm ui/views/style/platform_style_mac.mm
index 256bde37abf47..9ddfa6fc59f0a 100644
--- ui/views/style/platform_style_mac.mm
+++ ui/views/style/platform_style_mac.mm
@@ -43,7 +43,7 @@ const bool PlatformStyle::kTableViewSupportsKeyboardNavigationByCell = false;
const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
const bool PlatformStyle::kUseRipples = false;
const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = true;
-const bool PlatformStyle::kAdjustBubbleIfOffscreen = false;
+const bool PlatformStyle::kAdjustBubbleIfOffscreen = true;
const View::FocusBehavior PlatformStyle::kDefaultFocusBehavior =
View::FocusBehavior::ACCESSIBLE_ONLY;

View File

@@ -0,0 +1,42 @@
diff --git ui/display/screen.cc ui/display/screen.cc
index b74a058c4034e..441ccadf6a729 100644
--- ui/display/screen.cc
+++ ui/display/screen.cc
@@ -107,13 +107,13 @@ base::TimeDelta Screen::CalculateIdleTime() const {
gfx::Rect Screen::ScreenToDIPRectInWindow(gfx::NativeWindow window,
const gfx::Rect& screen_rect) const {
float scale = GetDisplayNearestWindow(window).device_scale_factor();
- return ScaleToEnclosingRect(screen_rect, 1.0f / scale);
+ return ScaleToEnclosedRect(screen_rect, 1.0f / scale);
}
gfx::Rect Screen::DIPToScreenRectInWindow(gfx::NativeWindow window,
const gfx::Rect& dip_rect) const {
float scale = GetDisplayNearestWindow(window).device_scale_factor();
- return ScaleToEnclosingRect(dip_rect, scale);
+ return ScaleToEnclosedRect(dip_rect, scale);
}
bool Screen::GetDisplayWithDisplayId(int64_t display_id,
diff --git ui/display/win/screen_win.cc ui/display/win/screen_win.cc
index 1bddf0a8b84b4..da4b443f5f5a9 100644
--- ui/display/win/screen_win.cc
+++ ui/display/win/screen_win.cc
@@ -580,7 +580,7 @@ gfx::Rect ScreenWin::ScreenToDIPRect(HWND hwnd, const gfx::Rect& pixel_bounds) {
gfx::PointF(pixel_bounds.origin()), screen_win_display));
const float scale_factor =
1.0f / screen_win_display.display().device_scale_factor();
- return {origin, ScaleToEnclosingRect(pixel_bounds, scale_factor).size()};
+ return {origin, ScaleToEnclosedRect(pixel_bounds, scale_factor).size()};
}
// static
@@ -595,7 +595,7 @@ gfx::Rect ScreenWin::DIPToScreenRect(HWND hwnd, const gfx::Rect& dip_bounds) {
const gfx::Point origin =
display::win::DIPToScreenPoint(dip_bounds.origin(), screen_win_display);
const float scale_factor = screen_win_display.display().device_scale_factor();
- return {origin, ScaleToEnclosingRect(dip_bounds, scale_factor).size()};
+ return {origin, ScaleToEnclosedRect(dip_bounds, scale_factor).size()};
}
// static

View File

@@ -178,10 +178,10 @@ index ba7f48e90026c..a509cc4565e9f 100644
void CookieManager::SetForceKeepSessionState() {
diff --git services/network/network_context.cc services/network/network_context.cc
index 660df7d04bff9..f3cb3381ce462 100644
index 5447074c168f6..793fa6fa439df 100644
--- services/network/network_context.cc
+++ services/network/network_context.cc
@@ -2328,16 +2328,20 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
@@ -2331,16 +2331,20 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
network_service_->network_quality_estimator());
}

View File

@@ -1,8 +1,8 @@
diff --git base/trace_event/builtin_categories.h base/trace_event/builtin_categories.h
index caf0822f9c14c..a052f4265212c 100644
index 84d698ad0a8b3..5e216a505e99e 100644
--- base/trace_event/builtin_categories.h
+++ base/trace_event/builtin_categories.h
@@ -63,6 +63,8 @@
@@ -64,6 +64,8 @@
X("cc") \
X("cc.debug") \
X("cdp.perf") \

View File

@@ -0,0 +1,27 @@
diff --git chrome/browser/ui/views/chrome_views_delegate_linux.cc chrome/browser/ui/views/chrome_views_delegate_linux.cc
index ecc07a2a60505..82a379fa65e68 100644
--- chrome/browser/ui/views/chrome_views_delegate_linux.cc
+++ chrome/browser/ui/views/chrome_views_delegate_linux.cc
@@ -52,6 +52,8 @@ NativeWidgetType GetNativeWidgetTypeForInitParams(
return NativeWidgetType::DESKTOP_NATIVE_WIDGET_AURA;
return (params.parent &&
+ (params.child ||
+ params.type == views::Widget::InitParams::TYPE_BUBBLE) &&
params.type != views::Widget::InitParams::TYPE_MENU &&
params.type != views::Widget::InitParams::TYPE_TOOLTIP)
? NativeWidgetType::NATIVE_WIDGET_AURA
diff --git ui/views/test/desktop_test_views_delegate_aura.cc ui/views/test/desktop_test_views_delegate_aura.cc
index 110eab7eec92a..2bfc96b6c439d 100644
--- ui/views/test/desktop_test_views_delegate_aura.cc
+++ ui/views/test/desktop_test_views_delegate_aura.cc
@@ -27,7 +27,8 @@ void DesktopTestViewsDelegate::OnBeforeWidgetInit(
if (params->native_widget)
return;
- if (params->parent && params->type != views::Widget::InitParams::TYPE_MENU &&
+ if (params->parent && params->child &&
+ params->type != views::Widget::InitParams::TYPE_MENU &&
params->type != views::Widget::InitParams::TYPE_TOOLTIP) {
params->native_widget = new views::NativeWidgetAura(delegate);
} else {

View File

@@ -29,19 +29,20 @@
#define ID_TESTS_OTHER_TESTS 32702
#define ID_TESTS_WINDOW_NEW 32703
#define ID_TESTS_WINDOW_POPUP 32704
#define ID_TESTS_PRINT 32705
#define ID_TESTS_REQUEST 32706
#define ID_TESTS_TRACING_BEGIN 32707
#define ID_TESTS_TRACING_END 32708
#define ID_TESTS_ZOOM_IN 32709
#define ID_TESTS_ZOOM_OUT 32710
#define ID_TESTS_ZOOM_RESET 32711
#define ID_TESTS_OSR_FPS 32712
#define ID_TESTS_OSR_DSF 32713
#define ID_TESTS_PRINT_TO_PDF 32714
#define ID_TESTS_MUTE_AUDIO 32715
#define ID_TESTS_UNMUTE_AUDIO 32716
#define ID_TESTS_LAST 32716
#define ID_TESTS_WINDOW_DIALOG 32705
#define ID_TESTS_PRINT 32706
#define ID_TESTS_REQUEST 32707
#define ID_TESTS_TRACING_BEGIN 32708
#define ID_TESTS_TRACING_END 32709
#define ID_TESTS_ZOOM_IN 32710
#define ID_TESTS_ZOOM_OUT 32711
#define ID_TESTS_ZOOM_RESET 32712
#define ID_TESTS_OSR_FPS 32713
#define ID_TESTS_OSR_DSF 32714
#define ID_TESTS_PRINT_TO_PDF 32715
#define ID_TESTS_MUTE_AUDIO 32716
#define ID_TESTS_UNMUTE_AUDIO 32717
#define ID_TESTS_LAST 32717
#define IDC_STATIC -1
#define IDS_BINDING_HTML 1000
#define IDS_DIALOGS_HTML 1001

View File

@@ -20,10 +20,23 @@
namespace client {
enum class WindowType {
NORMAL,
// The window is hosting an extension app.
EXTENSION,
// The window is a modal dialog.
DIALOG,
};
// Used to configure how a RootWindow is created.
struct RootWindowConfig {
RootWindowConfig();
// Configure the window type.
WindowType window_type = WindowType::NORMAL;
// If true the window will always display above other windows.
bool always_on_top = false;
@@ -33,9 +46,6 @@ struct RootWindowConfig {
// If true the window will use off-screen rendering.
bool with_osr = false;
// If true the window is hosting an extension app.
bool with_extension = false;
// If true the window will be created initially hidden.
bool initially_hidden = false;

View File

@@ -119,7 +119,7 @@ void RootWindowGtk::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
always_on_top_ = config->always_on_top;
with_osr_ = config->with_osr;
with_extension_ = config->with_extension;
with_extension_ = config->window_type == WindowType::EXTENSION;
start_rect_ = config->bounds;
CreateBrowserWindow(config->url);

View File

@@ -279,7 +279,7 @@ void RootWindowMacImpl::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
with_osr_ = config->with_osr;
with_extension_ = config->with_extension;
with_extension_ = config->window_type == WindowType::EXTENSION;
if (!config->bounds.IsEmpty()) {
// Initial state was specified via the config object.

View File

@@ -183,9 +183,9 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsExtension(
// We'll show the window when the desired size becomes available via
// ClientHandler::OnAutoResize.
auto config = std::make_unique<RootWindowConfig>();
config->window_type = WindowType::EXTENSION;
config->with_controls = with_controls;
config->with_osr = with_osr;
config->with_extension = true;
config->initially_hidden = true;
config->source_bounds = source_bounds;
config->parent_window = parent_window;

View File

@@ -184,7 +184,7 @@ ClientWindowHandle RootWindowViews::GetWindowHandle() const {
bool RootWindowViews::WithExtension() const {
DCHECK(initialized_);
return config_->with_extension;
return config_->window_type == WindowType::EXTENSION;
}
bool RootWindowViews::WithControls() {
@@ -192,11 +192,6 @@ bool RootWindowViews::WithControls() {
return config_->with_controls;
}
bool RootWindowViews::WithExtension() {
DCHECK(initialized_);
return config_->with_extension;
}
void RootWindowViews::OnExtensionsChanged(const ExtensionSet& extensions) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute this method on the UI thread.
@@ -254,6 +249,10 @@ void RootWindowViews::OnViewsWindowClosing(CefRefPtr<ViewsWindow> window) {
CEF_REQUIRE_UI_THREAD();
DCHECK(window_);
if (config_->window_type != WindowType::NORMAL) {
return;
}
cef_show_state_t show_state;
std::optional<CefRect> dip_bounds;
if (window_->GetWindowRestorePreferences(show_state, dip_bounds)) {
@@ -517,7 +516,7 @@ void RootWindowViews::InitOnUIThread(
// Initial state was specified via the config object.
initial_bounds_ = config_->bounds;
initial_show_state_ = config_->show_state;
} else {
} else if (config_->window_type == WindowType::NORMAL) {
// Initial state may be specified via the command-line or global
// preferences.
std::optional<CefRect> bounds;
@@ -556,8 +555,8 @@ void RootWindowViews::CreateViewsWindow(
#endif
// Create the ViewsWindow. It will show itself after creation.
ViewsWindow::Create(this, client_handler_, config_->url, settings,
request_context);
ViewsWindow::Create(config_->window_type, this, client_handler_, config_->url,
settings, request_context);
}
void RootWindowViews::NotifyViewsWindowDestroyed() {

View File

@@ -53,7 +53,6 @@ class RootWindowViews : public RootWindow,
// ViewsWindow::Delegate methods:
bool WithControls() override;
bool WithExtension() override;
bool InitiallyHidden() override;
CefRefPtr<CefWindow> GetParentWindow() override;
CefRect GetInitialBounds() override;

View File

@@ -133,7 +133,7 @@ void RootWindowWin::Init(RootWindow::Delegate* delegate,
with_controls_ = config->with_controls;
always_on_top_ = config->always_on_top;
with_osr_ = config->with_osr;
with_extension_ = config->with_extension;
with_extension_ = config->window_type == WindowType::EXTENSION;
CreateBrowserWindow(config->url);

View File

@@ -13,6 +13,7 @@
#include "include/cef_parser.h"
#include "include/cef_task.h"
#include "include/cef_trace.h"
#include "include/views/cef_browser_view.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "tests/cefclient/browser/binding_test.h"
@@ -145,6 +146,20 @@ void RunPopupWindowTest(CefRefPtr<CefBrowser> browser) {
"window.open('https://www.google.com');", "about:blank", 0);
}
void RunDialogWindowTest(CefRefPtr<CefBrowser> browser) {
auto browser_view = CefBrowserView::GetForBrowser(browser);
if (!browser_view) {
LOG(ERROR) << "Dialog windows require Views";
return;
}
auto config = std::make_unique<RootWindowConfig>();
config->window_type = WindowType::DIALOG;
config->parent_window = browser_view->GetWindow();
MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
std::move(config));
}
void ModifyZoom(CefRefPtr<CefBrowser> browser, double delta) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
@@ -547,6 +562,9 @@ void RunTest(CefRefPtr<CefBrowser> browser, int id) {
case ID_TESTS_WINDOW_POPUP:
RunPopupWindowTest(browser);
break;
case ID_TESTS_WINDOW_DIALOG:
RunDialogWindowTest(browser);
break;
case ID_TESTS_REQUEST:
RunRequestTest(browser);
break;

View File

@@ -44,9 +44,12 @@ char16_t GetMnemonic(const std::u16string& title) {
} // namespace
ViewsMenuBar::ViewsMenuBar(Delegate* delegate, int menu_id_start)
ViewsMenuBar::ViewsMenuBar(Delegate* delegate,
int menu_id_start,
bool use_bottom_controls)
: delegate_(delegate),
id_start_(menu_id_start),
use_bottom_controls_(use_bottom_controls),
id_next_(menu_id_start),
last_nav_with_keyboard_(false) {
DCHECK(delegate_);
@@ -164,12 +167,29 @@ void ViewsMenuBar::OnMenuButtonPressed(
CefRefPtr<CefMenuButtonPressedLock> button_pressed_lock) {
CefRefPtr<CefMenuModel> menu_model = GetMenuModel(menu_button->GetID());
const auto button_bounds = menu_button->GetBoundsInScreen();
// Adjust menu position to align with the button.
CefPoint point = screen_point;
if (CefIsRTL()) {
point.x += menu_button->GetBounds().width - 4;
point.x += button_bounds.width - 4;
} else {
point.x -= menu_button->GetBounds().width - 4;
point.x -= button_bounds.width - 4;
}
if (use_bottom_controls_) {
const auto display_bounds =
menu_button->GetWindow()->GetDisplay()->GetWorkArea();
const int available_height = display_bounds.y + display_bounds.height -
button_bounds.y - button_bounds.height;
// Approximation of the menu height.
const int menu_height =
static_cast<int>(menu_model->GetCount()) * button_bounds.height;
if (menu_height > available_height) {
// The menu will go upwards, so place it above the button.
point.y -= button_bounds.height - 8;
}
}
// Keep track of the current |last_nav_with_keyboard_| status and restore it
@@ -230,6 +250,10 @@ void ViewsMenuBar::MouseOutsideMenu(CefRefPtr<CefMenuModel> menu_model,
CefRefPtr<CefView> button = panel_->GetViewForID(id);
CefRect button_bounds = button->GetBounds();
// Adjust for window coordinates.
button_bounds.y += panel_bounds.y;
if (CefIsRTL()) {
// Adjust for right-to-left button layout.
button_bounds.x =

View File

@@ -39,7 +39,7 @@ class ViewsMenuBar : public CefMenuButtonDelegate, public CefMenuModelDelegate {
// |menu_id_start| is the ID for the first CefMenuButton in the bar. An ID
// range starting with |menu_id_start| and extending for a reasonable distance
// should be reserved in the client for MenuBar usage.
ViewsMenuBar(Delegate* delegate, int menu_id_start);
ViewsMenuBar(Delegate* delegate, int menu_id_start, bool use_bottom_controls);
// Returns true if |menu_id| exists in the menu bar.
bool HasMenuId(int menu_id) const;
@@ -106,6 +106,7 @@ class ViewsMenuBar : public CefMenuButtonDelegate, public CefMenuModelDelegate {
Delegate* delegate_; // Not owned by this object.
const int id_start_;
const bool use_bottom_controls_;
int id_next_;
CefRefPtr<CefPanel> panel_;
std::vector<CefRefPtr<CefMenuModel>> models_;

View File

@@ -47,25 +47,31 @@ std::array<ViewsOverlayControls::Command, 3> GetButtons() {
#endif
}
cef_docking_mode_t GetPanelDockingMode() {
cef_docking_mode_t GetPanelDockingMode(bool use_bottom_controls) {
#if defined(OS_MAC)
return CEF_DOCKING_MODE_TOP_LEFT;
return use_bottom_controls ? CEF_DOCKING_MODE_BOTTOM_LEFT
: CEF_DOCKING_MODE_TOP_LEFT;
#else
return CEF_DOCKING_MODE_TOP_RIGHT;
return use_bottom_controls ? CEF_DOCKING_MODE_BOTTOM_RIGHT
: CEF_DOCKING_MODE_TOP_RIGHT;
#endif
}
cef_docking_mode_t GetMenuDockingMode() {
cef_docking_mode_t GetMenuDockingMode(bool use_bottom_controls) {
#if defined(OS_MAC)
return CEF_DOCKING_MODE_TOP_RIGHT;
return use_bottom_controls ? CEF_DOCKING_MODE_BOTTOM_RIGHT
: CEF_DOCKING_MODE_TOP_RIGHT;
#else
return CEF_DOCKING_MODE_TOP_LEFT;
return use_bottom_controls ? CEF_DOCKING_MODE_BOTTOM_LEFT
: CEF_DOCKING_MODE_TOP_LEFT;
#endif
}
} // namespace
ViewsOverlayControls::ViewsOverlayControls(bool with_window_buttons)
: with_window_buttons_(with_window_buttons) {}
ViewsOverlayControls::ViewsOverlayControls(bool with_window_buttons,
bool use_bottom_controls)
: with_window_buttons_(with_window_buttons),
use_bottom_controls_(use_bottom_controls) {}
void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
CefRefPtr<CefMenuButton> menu_button,
@@ -78,6 +84,13 @@ void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
window_ = window;
window_maximized_ = window_->IsMaximized();
CefInsets insets;
if (use_bottom_controls_) {
insets.Set(0, kInsets, kInsets, kInsets);
} else {
insets.Set(kInsets, kInsets, 0, kInsets);
}
if (with_window_buttons_) {
// Window control buttons. These controls are currently text which means
// that we can't use a transparent background because subpixel text
@@ -94,15 +107,17 @@ void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
for (auto button : GetButtons()) {
panel_->AddChildView(CreateButton(button));
}
panel_controller_ = window->AddOverlayView(panel_, GetPanelDockingMode());
panel_controller_->SetInsets(CefInsets(kInsets, kInsets, 0, kInsets));
panel_controller_ = window->AddOverlayView(
panel_, GetPanelDockingMode(use_bottom_controls_));
panel_controller_->SetInsets(insets);
panel_controller_->SetVisible(true);
}
// Menu button.
menu_button->SetBackgroundColor(kBackgroundColor);
menu_controller_ = window_->AddOverlayView(menu_button, GetMenuDockingMode());
menu_controller_->SetInsets(CefInsets(kInsets, kInsets, 0, kInsets));
menu_controller_ = window_->AddOverlayView(
menu_button, GetMenuDockingMode(use_bottom_controls_));
menu_controller_->SetInsets(insets);
menu_controller_->SetVisible(true);
// Location bar. Will be made visible in UpdateControls().
@@ -130,10 +145,11 @@ void ViewsOverlayControls::Destroy() {
void ViewsOverlayControls::UpdateControls() {
// Update location bar size, position and visibility.
auto bounds = window_->GetBounds();
const auto window_bounds = window_->GetBounds();
auto bounds = window_bounds;
bounds.x = kLocationBarPadding;
bounds.width -= kLocationBarPadding * 2;
bounds.y = kInsets;
if (is_chrome_toolbar_) {
// Fit the standard Chrome toolbar.
const auto preferred_size = location_bar_->GetPreferredSize();
@@ -142,6 +158,13 @@ void ViewsOverlayControls::UpdateControls() {
} else {
bounds.height = menu_controller_->GetSize().height;
}
if (use_bottom_controls_) {
bounds.y = window_bounds.height - bounds.height - kInsets;
} else {
bounds.y = kInsets;
}
if (bounds.width < kLocationBarPadding * 2) {
// Not enough space.
location_controller_->SetVisible(false);

View File

@@ -25,7 +25,7 @@ class ViewsOverlayControls : public CefButtonDelegate {
kClose,
};
explicit ViewsOverlayControls(bool with_window_buttons);
ViewsOverlayControls(bool with_window_buttons, bool use_bottom_controls);
void Initialize(CefRefPtr<CefWindow> window,
CefRefPtr<CefMenuButton> menu_button,
@@ -54,6 +54,7 @@ class ViewsOverlayControls : public CefButtonDelegate {
CefRefPtr<CefPanel> panel_;
CefRefPtr<CefOverlayController> panel_controller_;
const bool with_window_buttons_;
const bool use_bottom_controls_;
// Location bar.
CefRefPtr<CefView> location_bar_;

View File

@@ -90,6 +90,7 @@ void AddTestMenuItems(CefRefPtr<CefMenuModel> test_menu) {
test_menu->AddItem(ID_TESTS_GETTEXT, "Get Text");
test_menu->AddItem(ID_TESTS_WINDOW_NEW, "New Window");
test_menu->AddItem(ID_TESTS_WINDOW_POPUP, "Popup Window");
test_menu->AddItem(ID_TESTS_WINDOW_DIALOG, "Dialog Window");
test_menu->AddItem(ID_TESTS_REQUEST, "Request");
test_menu->AddItem(ID_TESTS_ZOOM_IN, "Zoom In");
test_menu->AddItem(ID_TESTS_ZOOM_OUT, "Zoom Out");
@@ -131,6 +132,7 @@ CefBrowserViewDelegate::ChromeToolbarType CalculateChromeToolbarType(
// static
CefRefPtr<ViewsWindow> ViewsWindow::Create(
WindowType type,
Delegate* delegate,
CefRefPtr<CefClient> client,
const CefString& url,
@@ -140,7 +142,8 @@ CefRefPtr<ViewsWindow> ViewsWindow::Create(
DCHECK(delegate);
// Create a new ViewsWindow.
CefRefPtr<ViewsWindow> views_window = new ViewsWindow(delegate, nullptr);
CefRefPtr<ViewsWindow> views_window =
new ViewsWindow(type, delegate, nullptr);
// Create a new BrowserView.
CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
@@ -158,7 +161,26 @@ CefRefPtr<ViewsWindow> ViewsWindow::Create(
void ViewsWindow::Show() {
CEF_REQUIRE_UI_THREAD();
if (window_) {
window_->Show();
if (type_ == WindowType::DIALOG) {
if (use_window_modal_dialog_) {
// Show as a window modal dialog (IsWindowModalDialog() will return
// true).
window_->Show();
} else {
CefRefPtr<CefBrowserView> browser_view;
if (auto parent_window = delegate_->GetParentWindow()) {
if (auto view = parent_window->GetViewForID(ID_BROWSER_VIEW)) {
browser_view = view->AsBrowserView();
}
}
CHECK(browser_view);
// Show as a browser modal dialog (relative to |browser_view|).
window_->ShowAsBrowserModalDialog(browser_view);
}
} else {
window_->Show();
}
}
if (browser_view_ && !window_->IsMinimized()) {
// Give keyboard focus to the BrowserView.
@@ -324,7 +346,7 @@ void ViewsWindow::TakeFocus(bool next) {
}
if (chrome_toolbar_type_ == CEF_CTT_NORMAL) {
top_toolbar_->RequestFocus();
toolbar_->RequestFocus();
} else if (location_bar_) {
// Give focus to the location bar.
location_bar_->RequestFocus();
@@ -430,7 +452,7 @@ CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
DCHECK(popup_delegate != delegate_);
// Create a new ViewsWindow for the popup BrowserView.
return new ViewsWindow(popup_delegate, nullptr);
return new ViewsWindow(WindowType::NORMAL, popup_delegate, nullptr);
}
bool ViewsWindow::OnPopupBrowserViewCreated(
@@ -528,14 +550,30 @@ void ViewsWindow::OnMenuButtonPressed(
DCHECK(with_controls_ || with_overlay_controls_);
DCHECK_EQ(ID_MENU_BUTTON, id);
const auto button_bounds = menu_button->GetBoundsInScreen();
auto point = screen_point;
if (with_overlay_controls_) {
// Align the menu correctly under the button.
const int button_width = menu_button->GetSize().width;
if (CefIsRTL()) {
point.x += button_width - 4;
point.x += button_bounds.width - 4;
} else {
point.x -= button_width - 4;
point.x -= button_bounds.width - 4;
}
}
if (use_bottom_controls_) {
const auto display_bounds =
menu_button->GetWindow()->GetDisplay()->GetWorkArea();
const int available_height = display_bounds.y + display_bounds.height -
button_bounds.y - button_bounds.height;
// Approximation of the menu height.
const int menu_height =
static_cast<int>(button_menu_model_->GetCount()) * button_bounds.height;
if (menu_height > available_height) {
// The menu will go upwards, so place it above the button.
point.y -= button_bounds.height - 8;
}
}
@@ -591,18 +629,18 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
window_ = window;
window_->SetID(ID_WINDOW);
with_controls_ = delegate_->WithControls();
delegate_->OnViewsWindowCreated(this);
const CefRect bounds = delegate_->GetInitialBounds();
if (bounds.IsEmpty()) {
// Size the Window and center it at the default size.
window_->CenterWindow(CefSize(kDefaultWidth, kDefaultHeight));
} else {
// Remember the bounds from the previous application run in case the user
// does not move or resize the window during this application run.
last_visible_bounds_ = bounds;
if (type_ == WindowType::NORMAL) {
const CefRect bounds = delegate_->GetInitialBounds();
if (bounds.IsEmpty()) {
// Size the Window and center it at the default size.
window_->CenterWindow(CefSize(kDefaultWidth, kDefaultHeight));
} else {
// Remember the bounds from the previous application run in case the user
// does not move or resize the window during this application run.
last_visible_bounds_ = bounds;
}
}
// Set the background color for regions that are not obscured by other Views.
@@ -628,7 +666,7 @@ void ViewsWindow::OnWindowCreated(CefRefPtr<CefWindow> window) {
// Add the BrowserView as the only child of the Window.
window_->AddChildView(browser_view_);
if (!delegate_->WithExtension()) {
if (type_ != WindowType::EXTENSION) {
// Choose a reasonable minimum window size.
minimum_window_size_ = CefSize(100, 100);
}
@@ -655,9 +693,9 @@ void ViewsWindow::OnWindowDestroyed(CefRefPtr<CefWindow> window) {
browser_view_ = nullptr;
button_menu_model_ = nullptr;
if (top_menu_bar_) {
top_menu_bar_->Reset();
top_menu_bar_ = nullptr;
if (menu_bar_) {
menu_bar_->Reset();
menu_bar_ = nullptr;
}
extensions_panel_ = nullptr;
menu_button_ = nullptr;
@@ -675,17 +713,17 @@ void ViewsWindow::OnWindowActivationChanged(CefRefPtr<CefWindow> window,
void ViewsWindow::OnWindowBoundsChanged(CefRefPtr<CefWindow> window,
const CefRect& new_bounds) {
if (!window->IsMinimized() && !window->IsMaximized() &&
!window->IsFullscreen()) {
if (type_ == WindowType::NORMAL && !window->IsMinimized() &&
!window->IsMaximized() && !window->IsFullscreen()) {
// Track the last visible bounds for window restore purposes.
last_visible_bounds_ = new_bounds;
}
#if defined(OS_MAC)
if (frameless_ && with_standard_buttons_ && top_toolbar_) {
auto insets = top_toolbar_->GetInsets();
if (frameless_ && with_standard_buttons_ && toolbar_) {
auto insets = toolbar_->GetInsets();
insets.left = window->IsFullscreen() ? 0 : kWindowButtonsWidth;
top_toolbar_->SetInsets(insets);
toolbar_->SetInsets(insets);
}
#endif
}
@@ -707,15 +745,21 @@ CefRefPtr<CefWindow> ViewsWindow::GetParentWindow(CefRefPtr<CefWindow> window,
CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefWindow> parent_window = delegate_->GetParentWindow();
if (parent_window) {
// Should be an extension window, in which case we want it to behave as a
// menu and allow activation.
DCHECK(delegate_->WithExtension());
*is_menu = true;
*can_activate_menu = true;
// Extension windows behave as a menu and allow activation.
if (type_ == WindowType::EXTENSION) {
*is_menu = true;
*can_activate_menu = true;
}
}
return parent_window;
}
bool ViewsWindow::IsWindowModalDialog(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD();
DCHECK(delegate_->GetParentWindow());
return use_window_modal_dialog_;
}
CefRect ViewsWindow::GetInitialBounds(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD();
const CefRect bounds = delegate_->GetInitialBounds();
@@ -756,8 +800,20 @@ bool ViewsWindow::GetTitlebarHeight(CefRefPtr<CefWindow> window,
bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD();
// Don't allow windows hosting extensions to resize.
return !delegate_->WithExtension();
// Only allow resize of normal windows.
return type_ == WindowType::NORMAL;
}
bool ViewsWindow::CanMaximize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD();
// Only allow maximize of normal windows.
return type_ == WindowType::NORMAL;
}
bool ViewsWindow::CanMinimize(CefRefPtr<CefWindow> window) {
CEF_REQUIRE_UI_THREAD();
// Only allow minimize of normal windows.
return type_ == WindowType::NORMAL;
}
bool ViewsWindow::OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
@@ -779,7 +835,7 @@ bool ViewsWindow::OnKeyEvent(CefRefPtr<CefWindow> window,
return false;
}
if (delegate_->WithExtension() && event.type == KEYEVENT_RAWKEYDOWN &&
if (type_ == WindowType::EXTENSION && event.type == KEYEVENT_RAWKEYDOWN &&
event.windows_key_code == VK_ESCAPE) {
// Close the extension window on escape.
Close(false);
@@ -806,13 +862,25 @@ bool ViewsWindow::OnKeyEvent(CefRefPtr<CefWindow> window,
return true;
}
if (menu_has_focus_ && top_menu_bar_) {
return top_menu_bar_->OnKeyEvent(event);
if (menu_has_focus_ && menu_bar_) {
return menu_bar_->OnKeyEvent(event);
}
return false;
}
CefSize ViewsWindow::GetPreferredSize(CefRefPtr<CefView> view) {
CEF_REQUIRE_UI_THREAD();
if (view->GetID() == ID_WINDOW && type_ == WindowType::DIALOG) {
// Preferred size for a browser modal dialog. The dialog will be shrunk to
// fit inside the parent browser view if necessary.
return CefSize(kDefaultWidth, kDefaultHeight);
}
return CefSize();
}
CefSize ViewsWindow::GetMinimumSize(CefRefPtr<CefView> view) {
CEF_REQUIRE_UI_THREAD();
@@ -830,14 +898,14 @@ void ViewsWindow::OnFocus(CefRefPtr<CefView> view) {
// Keep track of the non-menu view that was last focused.
if (last_focused_view_ != view_id &&
(!top_menu_bar_ || !top_menu_bar_->HasMenuId(view_id))) {
(!menu_bar_ || !menu_bar_->HasMenuId(view_id))) {
last_focused_view_ = view_id;
}
// When focus leaves the menu buttons make them unfocusable.
if (menu_has_focus_) {
if (top_menu_bar_) {
if (!top_menu_bar_->HasMenuId(view_id)) {
if (menu_bar_) {
if (!menu_bar_->HasMenuId(view_id)) {
SetMenuFocusable(false);
}
} else if (view_id != ID_MENU_BUTTON) {
@@ -850,7 +918,7 @@ void ViewsWindow::OnBlur(CefRefPtr<CefView> view) {
CEF_REQUIRE_UI_THREAD();
const int view_id = view->GetID();
if (view_id == ID_BROWSER_VIEW && delegate_->WithExtension()) {
if (view_id == ID_BROWSER_VIEW && type_ == WindowType::EXTENSION) {
// Close windows hosting extensions when the browser loses focus.
Close(false);
}
@@ -870,18 +938,25 @@ void ViewsWindow::OnWindowChanged(CefRefPtr<CefView> view, bool added) {
if (with_overlay_controls_) {
// Add window buttons if we don't have standard ones
const bool with_window_buttons = !with_standard_buttons_;
overlay_controls_ = new ViewsOverlayControls(with_window_buttons);
overlay_controls_ =
new ViewsOverlayControls(with_window_buttons, use_bottom_controls_);
overlay_controls_->Initialize(window_, CreateMenuButton(),
CreateLocationBar(),
chrome_toolbar_type_ != CEF_CTT_NONE);
}
} else {
// Remove any controls that may include the Chrome toolbar before removing
// the BrowserView.
if (overlay_controls_) {
// Overlay controls may include the Chrome toolbar, in which case they
// need to be removed before the BrowserView.
overlay_controls_->Destroy();
overlay_controls_ = nullptr;
location_bar_ = nullptr;
} else if (use_bottom_controls_) {
if (toolbar_) {
window_->RemoveChildView(toolbar_);
toolbar_ = nullptr;
location_bar_ = nullptr;
}
}
}
}
@@ -904,10 +979,11 @@ void ViewsWindow::MenuBarExecuteCommand(CefRefPtr<CefMenuModel> menu_model,
ExecuteCommand(menu_model, command_id, event_flags);
}
ViewsWindow::ViewsWindow(Delegate* delegate,
ViewsWindow::ViewsWindow(WindowType type,
Delegate* delegate,
CefRefPtr<CefBrowserView> browser_view)
: delegate_(delegate),
with_controls_(false),
: type_(type),
delegate_(delegate),
menu_has_focus_(false),
last_focused_view_(false) {
DCHECK(delegate_);
@@ -918,19 +994,22 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
const bool is_normal_type = type_ == WindowType::NORMAL;
with_controls_ = is_normal_type && delegate_->WithControls();
const bool hide_frame = command_line->HasSwitch(switches::kHideFrame);
const bool hide_overlays = command_line->HasSwitch(switches::kHideOverlays);
const bool hide_toolbar =
hide_frame && hide_overlays && !delegate_->WithControls();
const bool hide_overlays =
!is_normal_type || command_line->HasSwitch(switches::kHideOverlays);
const bool hide_toolbar = hide_overlays && !with_controls_;
const bool show_window_buttons =
command_line->HasSwitch(switches::kShowWindowButtons);
// Without a window frame.
frameless_ = hide_frame || delegate_->WithExtension();
frameless_ = hide_frame || type_ == WindowType::EXTENSION;
// With an overlay that mimics window controls.
with_overlay_controls_ =
hide_frame && !hide_overlays && !delegate_->WithControls();
with_overlay_controls_ = hide_frame && !hide_overlays && !with_controls_;
// If window has frame or flag passed explicitly
with_standard_buttons_ = !frameless_ || show_window_buttons;
@@ -947,13 +1026,18 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
chrome_toolbar_type_ = CalculateChromeToolbarType(toolbar_type, hide_toolbar,
with_overlay_controls_);
use_bottom_controls_ = command_line->HasSwitch(switches::kUseBottomControls);
#if !defined(OS_MAC)
// On Mac we don't show a top menu on the window. The options are available in
// the app menu instead.
if (!command_line->HasSwitch(switches::kHideTopMenu)) {
top_menu_bar_ = new ViewsMenuBar(this, ID_TOP_MENU_FIRST);
menu_bar_ = new ViewsMenuBar(this, ID_TOP_MENU_FIRST, use_bottom_controls_);
}
#endif
use_window_modal_dialog_ =
command_line->HasSwitch(switches::kUseWindowModalDialog);
}
void ViewsWindow::SetBrowserView(CefRefPtr<CefBrowserView> browser_view) {
@@ -974,10 +1058,10 @@ void ViewsWindow::CreateMenuModel() {
AddTestMenuItems(test_menu);
AddFileMenuItems(button_menu_model_);
if (top_menu_bar_) {
if (menu_bar_) {
// Add the menus to the top menu bar.
AddFileMenuItems(top_menu_bar_->CreateMenuModel("&File", nullptr));
AddTestMenuItems(top_menu_bar_->CreateMenuModel("&Tests", nullptr));
AddFileMenuItems(menu_bar_->CreateMenuModel("&File", nullptr));
AddTestMenuItems(menu_bar_->CreateMenuModel("&Tests", nullptr));
}
}
@@ -1051,20 +1135,20 @@ void ViewsWindow::AddControls() {
// Build the remainder of the UI now that the BrowserView has been added to
// the CefWindow. This is a requirement to use Chrome toolbars.
CefRefPtr<CefPanel> top_menu_panel;
if (top_menu_bar_) {
top_menu_panel = top_menu_bar_->GetMenuPanel();
CefRefPtr<CefPanel> menu_panel;
if (menu_bar_) {
menu_panel = menu_bar_->GetMenuPanel();
}
LabelButtons browse_buttons;
if (chrome_toolbar_type_ == CEF_CTT_NORMAL) {
// Chrome will provide a normal toolbar with location, menu, etc.
top_toolbar_ = browser_view_->GetChromeToolbar();
DCHECK(top_toolbar_);
toolbar_ = browser_view_->GetChromeToolbar();
DCHECK(toolbar_);
}
if (!top_toolbar_) {
if (!toolbar_) {
// Create the browse buttons.
browse_buttons.push_back(CreateBrowseButton("Back", ID_BACK_BUTTON));
browse_buttons.push_back(CreateBrowseButton("Forward", ID_FORWARD_BUTTON));
@@ -1074,47 +1158,56 @@ void ViewsWindow::AddControls() {
CreateLocationBar();
CreateMenuButton();
// Create the top panel.
CefRefPtr<CefPanel> top_panel = CefPanel::CreatePanel(nullptr);
// Create the toolbar panel.
CefRefPtr<CefPanel> panel = CefPanel::CreatePanel(nullptr);
// Use a horizontal box layout for |top_panel|.
CefBoxLayoutSettings top_panel_layout_settings;
top_panel_layout_settings.horizontal = true;
CefRefPtr<CefBoxLayout> top_panel_layout =
top_panel->SetToBoxLayout(top_panel_layout_settings);
// Use a horizontal box layout for |panel|.
CefBoxLayoutSettings panel_layout_settings;
panel_layout_settings.horizontal = true;
CefRefPtr<CefBoxLayout> panel_layout =
panel->SetToBoxLayout(panel_layout_settings);
// Add the buttons and URL textfield to |top_panel|.
for (auto& browse_button : browse_buttons)
top_panel->AddChildView(browse_button);
top_panel->AddChildView(location_bar_);
// Add the buttons and URL textfield to |panel|.
for (auto& browse_button : browse_buttons) {
panel->AddChildView(browse_button);
}
panel->AddChildView(location_bar_);
UpdateExtensionControls();
DCHECK(extensions_panel_);
top_panel->AddChildView(extensions_panel_);
panel->AddChildView(extensions_panel_);
top_panel->AddChildView(menu_button_);
views_style::ApplyTo(top_panel);
panel->AddChildView(menu_button_);
views_style::ApplyTo(panel);
// Allow |location| to grow and fill any remaining space.
top_panel_layout->SetFlexForView(location_bar_, 1);
panel_layout->SetFlexForView(location_bar_, 1);
top_toolbar_ = top_panel;
toolbar_ = panel;
}
#if defined(OS_MAC)
if (frameless_ && with_standard_buttons_) {
auto insets = top_toolbar_->GetInsets();
auto insets = toolbar_->GetInsets();
insets.left = kWindowButtonsWidth;
top_toolbar_->SetInsets(insets);
toolbar_->SetInsets(insets);
}
#endif
// Add the top panel and browser view to |window|.
int top_index = 0;
if (top_menu_panel) {
window_->AddChildViewAt(top_menu_panel, top_index++);
if (use_bottom_controls_) {
// Add the panel at the bottom of |window|.
window_->AddChildView(toolbar_);
if (menu_panel) {
window_->AddChildView(menu_panel);
}
} else {
// Add the panel at the top of |window|.
int index = 0;
if (menu_panel) {
window_->AddChildViewAt(menu_panel, index++);
}
window_->AddChildViewAt(toolbar_, index);
}
window_->AddChildViewAt(top_toolbar_, top_index);
// Lay out |window| so we can get the default button sizes.
window_->Layout();
@@ -1134,10 +1227,10 @@ void ViewsWindow::AddControls() {
menu_button_->GetBounds().width + 100;
}
// Minimum window height is the hight of the top toolbar plus some extra.
int min_height = top_toolbar_->GetBounds().height + 100;
if (top_menu_panel) {
min_height += top_menu_panel->GetBounds().height;
// Minimum window height is the hight of the toolbar plus some extra.
int min_height = toolbar_->GetBounds().height + 100;
if (menu_panel) {
min_height += menu_panel->GetBounds().height;
}
minimum_window_size_ = CefSize(min_width, min_height);
@@ -1157,8 +1250,8 @@ void ViewsWindow::SetMenuFocusable(bool focusable) {
return;
}
if (top_menu_bar_) {
top_menu_bar_->SetMenuFocusable(focusable);
if (menu_bar_) {
menu_bar_->SetMenuFocusable(focusable);
} else {
window_->GetViewForID(ID_MENU_BUTTON)->SetFocusable(focusable);
@@ -1189,10 +1282,10 @@ void ViewsWindow::ShowTopControls(bool show) {
return;
}
// Change the visibility of the top toolbar.
if (top_toolbar_->IsVisible() != show) {
top_toolbar_->SetVisible(show);
top_toolbar_->InvalidateLayout();
// Change the visibility of the toolbar.
if (toolbar_->IsVisible() != show) {
toolbar_->SetVisible(show);
toolbar_->InvalidateLayout();
}
}
@@ -1206,11 +1299,11 @@ void ViewsWindow::UpdateExtensionControls() {
if (!extensions_panel_) {
extensions_panel_ = CefPanel::CreatePanel(nullptr);
// Use a horizontal box layout for |top_panel|.
CefBoxLayoutSettings top_panel_layout_settings;
top_panel_layout_settings.horizontal = true;
CefRefPtr<CefBoxLayout> top_panel_layout =
extensions_panel_->SetToBoxLayout(top_panel_layout_settings);
// Use a horizontal box layout for |panel|.
CefBoxLayoutSettings panel_layout_settings;
panel_layout_settings.horizontal = true;
CefRefPtr<CefBoxLayout> panel_layout =
extensions_panel_->SetToBoxLayout(panel_layout_settings);
} else {
extensions_panel_->RemoveAllChildViews();
}

View File

@@ -25,6 +25,7 @@
#include "include/views/cef_window.h"
#include "include/views/cef_window_delegate.h"
#include "tests/cefclient/browser/image_cache.h"
#include "tests/cefclient/browser/root_window.h"
#include "tests/cefclient/browser/views_menu_bar.h"
#include "tests/cefclient/browser/views_overlay_controls.h"
@@ -48,9 +49,6 @@ class ViewsWindow : public CefBrowserViewDelegate,
// Return true if the window should show controls.
virtual bool WithControls() = 0;
// Return true if the window is hosting an extension.
virtual bool WithExtension() = 0;
// Return true if the window should be created initially hidden.
virtual bool InitiallyHidden() = 0;
@@ -102,6 +100,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
// Create a new top-level ViewsWindow hosting a browser with the specified
// configuration.
static CefRefPtr<ViewsWindow> Create(
WindowType type,
Delegate* delegate,
CefRefPtr<CefClient> client,
const CefString& url,
@@ -172,6 +171,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
CefRefPtr<CefWindow> GetParentWindow(CefRefPtr<CefWindow> window,
bool* is_menu,
bool* can_activate_menu) override;
bool IsWindowModalDialog(CefRefPtr<CefWindow> window) override;
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
cef_show_state_t GetInitialShowState(CefRefPtr<CefWindow> window) override;
bool IsFrameless(CefRefPtr<CefWindow> window) override;
@@ -179,12 +179,15 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
float* titlebar_height) override;
bool CanResize(CefRefPtr<CefWindow> window) override;
bool CanMaximize(CefRefPtr<CefWindow> window) override;
bool CanMinimize(CefRefPtr<CefWindow> window) override;
bool CanClose(CefRefPtr<CefWindow> window) override;
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) override;
bool OnKeyEvent(CefRefPtr<CefWindow> window,
const CefKeyEvent& event) override;
// CefViewDelegate methods:
CefSize GetPreferredSize(CefRefPtr<CefView> view) override;
CefSize GetMinimumSize(CefRefPtr<CefView> view) override;
void OnFocus(CefRefPtr<CefView> view) override;
void OnBlur(CefRefPtr<CefView> view) override;
@@ -201,7 +204,9 @@ class ViewsWindow : public CefBrowserViewDelegate,
// |delegate| is guaranteed to outlive this object.
// |browser_view| may be nullptr, in which case SetBrowserView() will be
// called.
ViewsWindow(Delegate* delegate, CefRefPtr<CefBrowserView> browser_view);
ViewsWindow(WindowType type,
Delegate* delegate,
CefRefPtr<CefBrowserView> browser_view);
void SetBrowserView(CefRefPtr<CefBrowserView> browser_view);
@@ -239,6 +244,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
void NudgeWindow();
const WindowType type_;
Delegate* delegate_; // Not owned by this object.
CefRefPtr<CefBrowserView> browser_view_;
bool frameless_;
@@ -246,11 +252,13 @@ class ViewsWindow : public CefBrowserViewDelegate,
bool with_overlay_controls_;
bool with_standard_buttons_;
ChromeToolbarType chrome_toolbar_type_;
bool use_window_modal_dialog_;
bool use_bottom_controls_;
CefRefPtr<CefWindow> window_;
CefRefPtr<CefMenuModel> button_menu_model_;
CefRefPtr<ViewsMenuBar> top_menu_bar_;
CefRefPtr<CefView> top_toolbar_;
CefRefPtr<ViewsMenuBar> menu_bar_;
CefRefPtr<CefView> toolbar_;
CefRefPtr<CefMenuButton> menu_button_;
CefRefPtr<CefView> location_bar_;
bool menu_has_focus_;

View File

@@ -40,6 +40,13 @@ NSMenuItem* GetMenuItemWithAction(NSMenu* menu, SEL action_selector) {
return nil;
}
void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
NSMenuItem* item = GetMenuItemWithAction(menu, action_selector);
if (item) {
[menu removeItem:item];
}
}
} // namespace
// Receives notifications from the application. Will delete itself when done.
@@ -57,6 +64,7 @@ NSMenuItem* GetMenuItemWithAction(NSMenu* menu, SEL action_selector) {
- (IBAction)menuTestsGetSource:(id)sender;
- (IBAction)menuTestsWindowNew:(id)sender;
- (IBAction)menuTestsWindowPopup:(id)sender;
- (IBAction)menuTestsWindowDialog:(id)sender;
- (IBAction)menuTestsRequest:(id)sender;
- (IBAction)menuTestsZoomIn:(id)sender;
- (IBAction)menuTestsZoomOut:(id)sender;
@@ -206,20 +214,18 @@ NSMenuItem* GetMenuItemWithAction(NSMenu* menu, SEL action_selector) {
// Set the delegate for application events.
[application setDelegate:self];
if (!with_osr_) {
// Remove the OSR-related menu items when OSR is disabled.
NSMenuItem* tests_menu = GetMenuBarMenuWithTag(8);
if (tests_menu) {
NSMenuItem* set_fps_item = GetMenuItemWithAction(
tests_menu.submenu, @selector(menuTestsSetFPS:));
if (set_fps_item) {
[tests_menu.submenu removeItem:set_fps_item];
}
NSMenuItem* set_scale_factor_item = GetMenuItemWithAction(
tests_menu.submenu, @selector(menuTestsSetScaleFactor:));
if (set_scale_factor_item) {
[tests_menu.submenu removeItem:set_scale_factor_item];
}
auto* main_context = client::MainContext::Get();
NSMenuItem* tests_menu = GetMenuBarMenuWithTag(8);
if (tests_menu) {
if (!with_osr_) {
// Remove the OSR-related menu items when not using OSR.
RemoveMenuItem(tests_menu.submenu, @selector(menuTestsSetFPS:));
RemoveMenuItem(tests_menu.submenu, @selector(menuTestsSetScaleFactor:));
}
if (!main_context->UseViews()) {
// Remove the Views-related menu items when not using Views.
RemoveMenuItem(tests_menu.submenu, @selector(menuTestsWindowDialog:));
}
}
@@ -228,7 +234,7 @@ NSMenuItem* GetMenuItemWithAction(NSMenu* menu, SEL action_selector) {
window_config->with_osr = with_osr_;
// Create the first window.
client::MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
main_context->GetRootWindowManager()->CreateRootWindow(
std::move(window_config));
}
@@ -262,6 +268,10 @@ NSMenuItem* GetMenuItemWithAction(NSMenu* menu, SEL action_selector) {
[self testsItemSelected:ID_TESTS_WINDOW_POPUP];
}
- (IBAction)menuTestsWindowDialog:(id)sender {
[self testsItemSelected:ID_TESTS_WINDOW_DIALOG];
}
- (IBAction)menuTestsRequest:(id)sender {
[self testsItemSelected:ID_TESTS_REQUEST];
}

View File

@@ -362,6 +362,12 @@
<action selector="menuTestsWindowPopup:" target="-2" id="8GQ-Ph-2iP"/>
</connections>
</menuItem>
<menuItem title="Dialog Window" id="a52-WG-ltZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="menuTestsWindowDialog:" target="-2" id="8GQ-Ph-2iQ"/>
</connections>
</menuItem>
<menuItem title="Request" id="Ymm-D1-9xh">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>

View File

@@ -274,14 +274,6 @@ class DownloadTestHandler : public TestHandler {
// ALT key will trigger download of custom protocol links.
SendClick(browser,
test_mode_ == CLICKED_INVALID ? EVENTFLAG_ALT_DOWN : 0);
if (is_clicked() && !is_clicked_and_downloaded()) {
// Destroy the test after a bit because there will be no further
// callbacks.
CefPostDelayedTask(
TID_UI, base::BindOnce(&DownloadTestHandler::DestroyTest, this),
200);
}
} else {
// Begin the download progammatically.
browser->GetHost()->StartDownload(kTestDownloadUrl);
@@ -339,6 +331,13 @@ class DownloadTestHandler : public TestHandler {
EXPECT_STREQ(download_url_.c_str(), url.ToString().c_str());
EXPECT_STREQ("GET", request_method.ToString().c_str());
if (is_clicked() && !is_clicked_and_downloaded()) {
// Destroy the test after a bit because there will be no further
// callbacks.
CefPostDelayedTask(
TID_UI, base::BindOnce(&DownloadTestHandler::DestroyTest, this), 200);
}
return test_mode_ != CLICKED_BLOCKED;
}

View File

@@ -150,7 +150,6 @@ void CefTestSuite::GetSettings(CefSettings& settings) const {
CefString(&settings.cache_path) = root_cache_path_;
CefString(&settings.root_cache_path) = root_cache_path_;
CefString(&settings.user_data_path) = root_cache_path_;
// Always expose the V8 gc() function to give tests finer-grained control over
// memory management.

View File

@@ -54,6 +54,8 @@ const char kUseDefaultPopup[] = "use-default-popup";
const char kUseClientDialogs[] = "use-client-dialogs";
const char kUseTestHttpServer[] = "use-test-http-server";
const char kShowWindowButtons[] = "show-window-buttons";
const char kUseWindowModalDialog[] = "use-window-modal-dialog";
const char kUseBottomControls[] = "use-bottom-controls";
} // namespace switches
} // namespace client

View File

@@ -48,6 +48,8 @@ extern const char kUseDefaultPopup[];
extern const char kUseClientDialogs[];
extern const char kUseTestHttpServer[];
extern const char kShowWindowButtons[];
extern const char kUseWindowModalDialog[];
extern const char kUseBottomControls[];
} // namespace switches
} // namespace client