chrome: Add callback for already running app relaunch (fixes #3609)
Adds a new CefBrowserProcessHandler::OnAlreadyRunningAppRelaunch callback for when an already running app is relaunched with the same CefSettings.root_cache_path. Client apps should check the CefInitialize() return value for early exit of the relaunch source process.
This commit is contained in:
parent
d6af79e7a6
commit
a25f89f9e4
2
BUILD.gn
2
BUILD.gn
|
@ -524,6 +524,8 @@ source_set("libcef_static") {
|
|||
"libcef/browser/chrome/chrome_content_browser_client_cef.h",
|
||||
"libcef/browser/chrome/chrome_context_menu_handler.cc",
|
||||
"libcef/browser/chrome/chrome_context_menu_handler.h",
|
||||
"libcef/browser/chrome/chrome_startup_browser_creator.cc",
|
||||
"libcef/browser/chrome/chrome_startup_browser_creator.h",
|
||||
"libcef/browser/chrome_crash_reporter_client_stub.cc",
|
||||
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.cc",
|
||||
"libcef/browser/chrome/extensions/chrome_mime_handler_view_guest_delegate_cef.h",
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=9b523fbf312a8a0cb1c743a3c8aca7bc9cc22bbc$
|
||||
// $hash=692f2719fc029131ce17a7c90abca178daadb63e$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_APP_CAPI_H_
|
||||
|
@ -133,10 +133,13 @@ CEF_EXPORT int cef_execute_process(const cef_main_args_t* args,
|
|||
|
||||
///
|
||||
/// This function should be called on the main application thread to initialize
|
||||
/// the CEF browser process. The |application| parameter may be NULL. A return
|
||||
/// value of true (1) indicates that it succeeded and false (0) indicates that
|
||||
/// it failed. The |windows_sandbox_info| parameter is only used on Windows and
|
||||
/// may be NULL (see cef_sandbox_win.h for details).
|
||||
/// the CEF browser process. The |application| parameter may be NULL. Returns
|
||||
/// true (1) if initialization succeeds. Returns false (0) if initialization
|
||||
/// fails or if early exit is desired (for example, due to process singleton
|
||||
/// relaunch behavior). If this function returns false (0) then the application
|
||||
/// should exit immediately without calling any other CEF functions. The
|
||||
/// |windows_sandbox_info| parameter is only used on Windows and may be NULL
|
||||
/// (see cef_sandbox_win.h for details).
|
||||
///
|
||||
CEF_EXPORT int cef_initialize(const cef_main_args_t* args,
|
||||
const struct _cef_settings_t* settings,
|
||||
|
@ -145,7 +148,8 @@ CEF_EXPORT int cef_initialize(const cef_main_args_t* args,
|
|||
|
||||
///
|
||||
/// This function should be called on the main application thread to shut down
|
||||
/// the CEF browser process before the application exits.
|
||||
/// the CEF browser process before the application exits. Do not call any other
|
||||
/// CEF functions after calling this function.
|
||||
///
|
||||
CEF_EXPORT void cef_shutdown(void);
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=a146316e075450f0a6f37cb45d14e15e0ac7be08$
|
||||
// $hash=9e91adb231d67a65ce02294a0806d7effd40d280$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_PROCESS_HANDLER_CAPI_H_
|
||||
|
@ -106,6 +106,30 @@ typedef struct _cef_browser_process_handler_t {
|
|||
struct _cef_browser_process_handler_t* self,
|
||||
struct _cef_command_line_t* command_line);
|
||||
|
||||
///
|
||||
/// Implement this function to provide app-specific behavior when an already
|
||||
/// running app is relaunched with the same CefSettings.root_cache_path value.
|
||||
/// For example, activate an existing app window or create a new app window.
|
||||
/// |command_line| will be read-only. Do not keep a reference to
|
||||
/// |command_line| outside of this function. Return true (1) if the relaunch
|
||||
/// is handled or false (0) for default relaunch behavior. Default behavior
|
||||
/// will create a new default styled Chrome window.
|
||||
///
|
||||
/// To avoid cache corruption only a single app instance is allowed to run for
|
||||
/// a given CefSettings.root_cache_path value. On relaunch the app checks a
|
||||
/// process singleton lock and then forwards the new launch arguments to the
|
||||
/// already running app process before exiting early. Client apps should
|
||||
/// therefore check the cef_initialize() return value for early exit before
|
||||
/// proceeding.
|
||||
///
|
||||
/// This function will be called on the browser process UI thread. Currently
|
||||
/// only used with the chrome runtime.
|
||||
///
|
||||
int(CEF_CALLBACK* on_already_running_app_relaunch)(
|
||||
struct _cef_browser_process_handler_t* self,
|
||||
struct _cef_command_line_t* command_line,
|
||||
const cef_string_t* current_directory);
|
||||
|
||||
///
|
||||
/// Called from any thread when work has been scheduled for the browser
|
||||
/// process main (UI) thread. This callback is used in combination with
|
||||
|
|
|
@ -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 "09b1cc5ff57703ab04bd555c4b24e8bc7c660cb6"
|
||||
#define CEF_API_HASH_UNIVERSAL "bbdc07e7c5ed2ae5398efdebdd1ed08801bc91ab"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "64478d96e4841bd34db245d65d390f2d25759e5e"
|
||||
#define CEF_API_HASH_PLATFORM "002e3391fd68b0a444dbb6cd1b2a19a4c181d935"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "8596f11f53a9100d69757d82208bb3d89d5bf524"
|
||||
#define CEF_API_HASH_PLATFORM "3e4f2433692dc8bb779314dce84b81d81d39d2c2"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "2f53b2bbce606c42c0c462be1b1e16199962d6b7"
|
||||
#define CEF_API_HASH_PLATFORM "4e707370d08d4639c41e7c8aa8027c4a6090eace"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -67,10 +67,13 @@ int CefExecuteProcess(const CefMainArgs& args,
|
|||
|
||||
///
|
||||
/// This function should be called on the main application thread to initialize
|
||||
/// the CEF browser process. The |application| parameter may be empty. A return
|
||||
/// value of true indicates that it succeeded and false indicates that it
|
||||
/// failed. The |windows_sandbox_info| parameter is only used on Windows and may
|
||||
/// be NULL (see cef_sandbox_win.h for details).
|
||||
/// the CEF browser process. The |application| parameter may be empty. Returns
|
||||
/// true if initialization succeeds. Returns false if initialization fails or if
|
||||
/// early exit is desired (for example, due to process singleton relaunch
|
||||
/// behavior). If this function returns false then the application should exit
|
||||
/// immediately without calling any other CEF functions. The
|
||||
/// |windows_sandbox_info| parameter is only used on Windows and may be NULL
|
||||
/// (see cef_sandbox_win.h for details).
|
||||
///
|
||||
/*--cef(api_hash_check,optional_param=application,
|
||||
optional_param=windows_sandbox_info)--*/
|
||||
|
@ -81,7 +84,8 @@ bool CefInitialize(const CefMainArgs& args,
|
|||
|
||||
///
|
||||
/// This function should be called on the main application thread to shut down
|
||||
/// the CEF browser process before the application exits.
|
||||
/// the CEF browser process before the application exits. Do not call any
|
||||
/// other CEF functions after calling this function.
|
||||
///
|
||||
/*--cef()--*/
|
||||
void CefShutdown();
|
||||
|
|
|
@ -97,6 +97,32 @@ class CefBrowserProcessHandler : public virtual CefBaseRefCounted {
|
|||
virtual void OnBeforeChildProcessLaunch(
|
||||
CefRefPtr<CefCommandLine> command_line) {}
|
||||
|
||||
///
|
||||
/// Implement this method to provide app-specific behavior when an already
|
||||
/// running app is relaunched with the same CefSettings.root_cache_path value.
|
||||
/// For example, activate an existing app window or create a new app window.
|
||||
/// |command_line| will be read-only. Do not keep a reference to
|
||||
/// |command_line| outside of this method. Return true if the relaunch is
|
||||
/// handled or false for default relaunch behavior. Default behavior will
|
||||
/// create a new default styled Chrome window.
|
||||
///
|
||||
/// To avoid cache corruption only a single app instance is allowed to run for
|
||||
/// a given CefSettings.root_cache_path value. On relaunch the app checks a
|
||||
/// process singleton lock and then forwards the new launch arguments to the
|
||||
/// already running app process before exiting early. Client apps should
|
||||
/// therefore check the CefInitialize() return value for early exit before
|
||||
/// proceeding.
|
||||
///
|
||||
/// This method will be called on the browser process UI thread. Currently
|
||||
/// only used with the chrome runtime.
|
||||
///
|
||||
/*--cef(optional_param=current_directory)--*/
|
||||
virtual bool OnAlreadyRunningAppRelaunch(
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Called from any thread when work has been scheduled for the browser
|
||||
/// process main (UI) thread. This callback is used in combination with
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "libcef/browser/chrome/chrome_browser_main_extra_parts_cef.h"
|
||||
|
||||
#include "libcef/browser/chrome/chrome_context_menu_handler.h"
|
||||
#include "libcef/browser/chrome/chrome_startup_browser_creator.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/file_dialog_runner.h"
|
||||
#include "libcef/browser/net/chrome_scheme_handler.h"
|
||||
|
@ -13,6 +14,10 @@
|
|||
#include "base/task/thread_pool.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
#include "base/linux_util.h"
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "chrome/browser/win/app_icon.h"
|
||||
#endif
|
||||
|
@ -38,6 +43,18 @@ void ChromeBrowserMainExtraPartsCef::PostProfileInit(Profile* profile,
|
|||
CefRequestContextImpl::CreateGlobalRequestContext(settings);
|
||||
}
|
||||
|
||||
void ChromeBrowserMainExtraPartsCef::PostBrowserStart() {
|
||||
// Register the callback before ChromeBrowserMainParts::PostBrowserStart
|
||||
// allows ProcessSingleton to begin processing messages.
|
||||
startup_browser_creator::RegisterProcessCommandLineCallback();
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// This may be called indirectly via StartupBrowserCreator::LaunchBrowser.
|
||||
// Call it here before blocking is disallowed to avoid assertions.
|
||||
base::GetLinuxDistro();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ChromeBrowserMainExtraPartsCef::PreMainMessageLoopRun() {
|
||||
background_task_runner_ = base::ThreadPool::CreateSingleThreadTaskRunner(
|
||||
{base::TaskPriority::BEST_EFFORT,
|
||||
|
|
|
@ -42,6 +42,7 @@ class ChromeBrowserMainExtraPartsCef : public ChromeBrowserMainExtraParts {
|
|||
private:
|
||||
// ChromeBrowserMainExtraParts overrides.
|
||||
void PostProfileInit(Profile* profile, bool is_initial_profile) override;
|
||||
void PostBrowserStart() override;
|
||||
void PreMainMessageLoopRun() override;
|
||||
|
||||
CefRefPtr<CefRequestContextImpl> global_request_context_;
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 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 "libcef/browser/chrome/chrome_startup_browser_creator.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "libcef/browser/browser_context.h"
|
||||
#include "libcef/common/app_manager.h"
|
||||
#include "libcef/common/command_line_impl.h"
|
||||
|
||||
#include "chrome/browser/ui/startup/startup_browser_creator.h"
|
||||
|
||||
namespace startup_browser_creator {
|
||||
|
||||
namespace {
|
||||
|
||||
bool ProcessCommandLineCallback(const base::CommandLine& command_line,
|
||||
const base::FilePath& cur_dir) {
|
||||
bool handled = false;
|
||||
|
||||
if (auto app = CefAppManager::Get()->GetApplication()) {
|
||||
if (auto handler = app->GetBrowserProcessHandler()) {
|
||||
CefRefPtr<CefCommandLineImpl> commandLinePtr(
|
||||
new CefCommandLineImpl(command_line));
|
||||
handled = handler->OnAlreadyRunningAppRelaunch(commandLinePtr.get(),
|
||||
cur_dir.value());
|
||||
std::ignore = commandLinePtr->Detach(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void RegisterProcessCommandLineCallback() {
|
||||
StartupBrowserCreator::RegisterProcessCommandLineCallback(
|
||||
base::BindRepeating(&ProcessCommandLineCallback));
|
||||
}
|
||||
|
||||
} // namespace startup_browser_creator
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_CHROME_CHROME_STARTUP_BROWSER_CREATOR_H_
|
||||
#define CEF_LIBCEF_BROWSER_CHROME_CHROME_STARTUP_BROWSER_CREATOR_H_
|
||||
#pragma once
|
||||
|
||||
namespace startup_browser_creator {
|
||||
|
||||
// Register the process launch command line callback.
|
||||
void RegisterProcessCommandLineCallback();
|
||||
|
||||
} // namespace startup_browser_creator
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_CHROME_CHROME_STARTUP_BROWSER_CREATOR_H_
|
|
@ -307,8 +307,15 @@ bool CefInitialize(const CefMainArgs& args,
|
|||
g_context = new CefContext();
|
||||
|
||||
// Initialize the global context.
|
||||
return g_context->Initialize(args, settings, application,
|
||||
windows_sandbox_info);
|
||||
if (!g_context->Initialize(args, settings, application,
|
||||
windows_sandbox_info)) {
|
||||
// Initialization failed. Delete the global context object.
|
||||
delete g_context;
|
||||
g_context = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefShutdown() {
|
||||
|
@ -469,10 +476,16 @@ bool CefContext::Initialize(const CefMainArgs& args,
|
|||
|
||||
main_runner_.reset(new CefMainRunner(settings_.multi_threaded_message_loop,
|
||||
settings_.external_message_pump));
|
||||
return main_runner_->Initialize(
|
||||
&settings_, application, args, windows_sandbox_info, &initialized_,
|
||||
base::BindOnce(&CefContext::OnContextInitialized,
|
||||
base::Unretained(this)));
|
||||
if (!main_runner_->Initialize(
|
||||
&settings_, application, args, windows_sandbox_info, &initialized_,
|
||||
base::BindOnce(&CefContext::OnContextInitialized,
|
||||
base::Unretained(this)))) {
|
||||
shutting_down_ = true;
|
||||
FinalizeShutdown();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefContext::RunMessageLoop() {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "base/synchronization/lock.h"
|
||||
#include "base/synchronization/waitable_event.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "chrome/common/chrome_result_codes.h"
|
||||
#include "components/crash/core/app/crash_switches.h"
|
||||
#include "content/app/content_main_runner_impl.h"
|
||||
#include "content/browser/scheduler/browser_task_executor.h"
|
||||
|
@ -227,15 +228,21 @@ bool CefMainRunner::Initialize(CefSettings* settings,
|
|||
settings->chrome_runtime ? RuntimeType::CHROME : RuntimeType::ALLOY, this,
|
||||
settings, application);
|
||||
|
||||
const int exit_code =
|
||||
int exit_code =
|
||||
ContentMainInitialize(args, windows_sandbox_info, &settings->no_sandbox);
|
||||
if (exit_code >= 0) {
|
||||
DCHECK(false) << "ContentMainInitialize failed";
|
||||
LOG(ERROR) << "ContentMainInitialize failed with exit code " << exit_code;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ContentMainRun(initialized, std::move(context_initialized))) {
|
||||
DCHECK(false) << "ContentMainRun failed";
|
||||
exit_code = ContentMainRun(initialized, std::move(context_initialized));
|
||||
if (exit_code != content::RESULT_CODE_NORMAL_EXIT) {
|
||||
// Some exit codes are used to exit early, but are otherwise a normal
|
||||
// result. Don't log for those codes.
|
||||
if (!chrome::IsNormalResultCode(
|
||||
static_cast<chrome::ResultCode>(exit_code))) {
|
||||
LOG(ERROR) << "ContentMainRun failed with exit code " << exit_code;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -383,10 +390,12 @@ int CefMainRunner::ContentMainInitialize(const CefMainArgs& args,
|
|||
main_runner_.get());
|
||||
}
|
||||
|
||||
bool CefMainRunner::ContentMainRun(bool* initialized,
|
||||
base::OnceClosure context_initialized) {
|
||||
int CefMainRunner::ContentMainRun(bool* initialized,
|
||||
base::OnceClosure context_initialized) {
|
||||
main_delegate_->BeforeMainThreadRun(multi_threaded_message_loop_);
|
||||
|
||||
int exit_code = -1;
|
||||
|
||||
if (multi_threaded_message_loop_) {
|
||||
// Detach the CommandLine from the main thread so that it can be
|
||||
// attached and modified from the UI thread going forward.
|
||||
|
@ -397,14 +406,15 @@ bool CefMainRunner::ContentMainRun(bool* initialized,
|
|||
base::WaitableEvent::InitialState::NOT_SIGNALED);
|
||||
|
||||
if (!CreateUIThread(base::BindOnce(
|
||||
[](CefMainRunner* runner, base::WaitableEvent* event) {
|
||||
[](CefMainRunner* runner, base::WaitableEvent* event,
|
||||
int* exit_code) {
|
||||
runner->main_delegate_->BeforeUIThreadInitialize();
|
||||
content::ContentMainRun(runner->main_runner_.get());
|
||||
*exit_code = content::ContentMainRun(runner->main_runner_.get());
|
||||
event->Signal();
|
||||
},
|
||||
base::Unretained(this),
|
||||
base::Unretained(&uithread_startup_event)))) {
|
||||
return false;
|
||||
base::Unretained(this), base::Unretained(&uithread_startup_event),
|
||||
base::Unretained(&exit_code)))) {
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
*initialized = true;
|
||||
|
@ -414,19 +424,23 @@ bool CefMainRunner::ContentMainRun(bool* initialized,
|
|||
} else {
|
||||
*initialized = true;
|
||||
main_delegate_->BeforeUIThreadInitialize();
|
||||
content::ContentMainRun(main_runner_.get());
|
||||
exit_code = content::ContentMainRun(main_runner_.get());
|
||||
}
|
||||
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
OnContextInitialized(std::move(context_initialized));
|
||||
} else {
|
||||
// Continue initialization on the UI thread.
|
||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefMainRunner::OnContextInitialized,
|
||||
base::Unretained(this),
|
||||
std::move(context_initialized)));
|
||||
if (exit_code == content::RESULT_CODE_NORMAL_EXIT) {
|
||||
// content::ContentMainRun was successful and we're not exiting early.
|
||||
if (CEF_CURRENTLY_ON_UIT()) {
|
||||
OnContextInitialized(std::move(context_initialized));
|
||||
} else {
|
||||
// Continue initialization on the UI thread.
|
||||
CEF_POST_TASK(CEF_UIT,
|
||||
base::BindOnce(&CefMainRunner::OnContextInitialized,
|
||||
base::Unretained(this),
|
||||
std::move(context_initialized)));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
void CefMainRunner::PreBrowserMain() {
|
||||
|
|
|
@ -59,7 +59,7 @@ class CefMainRunner : public CefMainRunnerHandler {
|
|||
int ContentMainInitialize(const CefMainArgs& args,
|
||||
void* windows_sandbox_info,
|
||||
int* no_sandbox);
|
||||
bool ContentMainRun(bool* initialized, base::OnceClosure context_initialized);
|
||||
int ContentMainRun(bool* initialized, base::OnceClosure context_initialized);
|
||||
|
||||
// CefMainRunnerHandler methods:
|
||||
void PreBrowserMain() override;
|
||||
|
|
|
@ -18,6 +18,11 @@ CefCommandLineImpl::CefCommandLineImpl(base::CommandLine* value,
|
|||
read_only,
|
||||
nullptr) {}
|
||||
|
||||
CefCommandLineImpl::CefCommandLineImpl(const base::CommandLine& value)
|
||||
: CefCommandLineImpl(const_cast<base::CommandLine*>(&value),
|
||||
/*will_delete=*/false,
|
||||
/*read_only=*/true) {}
|
||||
|
||||
bool CefCommandLineImpl::IsValid() {
|
||||
return !detached();
|
||||
}
|
||||
|
|
|
@ -15,10 +15,16 @@
|
|||
class CefCommandLineImpl
|
||||
: public CefValueBase<CefCommandLine, base::CommandLine> {
|
||||
public:
|
||||
// If |will_delete=false| make sure to call |std::ignore =
|
||||
// obj->Detach(nullptr);| to invalidate this object when the client should no
|
||||
// longer be accessing it.
|
||||
CefCommandLineImpl(base::CommandLine* value,
|
||||
bool will_delete,
|
||||
bool read_only);
|
||||
|
||||
// Shortcut for |will_delete=false|, |read_only=true|.
|
||||
explicit CefCommandLineImpl(const base::CommandLine& value);
|
||||
|
||||
CefCommandLineImpl(const CefCommandLineImpl&) = delete;
|
||||
CefCommandLineImpl& operator=(const CefCommandLineImpl&) = delete;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=5b13f3f4cac21266cab10ca5153ccebe99d6869b$
|
||||
// $hash=257c836d87c9caa665028dde1ff768569bef816b$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/browser_process_handler_cpptoc.h"
|
||||
|
@ -79,6 +79,33 @@ void CEF_CALLBACK browser_process_handler_on_before_child_process_launch(
|
|||
CefCommandLineCToCpp::Wrap(command_line));
|
||||
}
|
||||
|
||||
int CEF_CALLBACK browser_process_handler_on_already_running_app_relaunch(
|
||||
struct _cef_browser_process_handler_t* self,
|
||||
struct _cef_command_line_t* command_line,
|
||||
const cef_string_t* current_directory) {
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
DCHECK(self);
|
||||
if (!self) {
|
||||
return 0;
|
||||
}
|
||||
// Verify param: command_line; type: refptr_diff
|
||||
DCHECK(command_line);
|
||||
if (!command_line) {
|
||||
return 0;
|
||||
}
|
||||
// Unverified params: current_directory
|
||||
|
||||
// Execute
|
||||
bool _retval =
|
||||
CefBrowserProcessHandlerCppToC::Get(self)->OnAlreadyRunningAppRelaunch(
|
||||
CefCommandLineCToCpp::Wrap(command_line),
|
||||
CefString(current_directory));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
void CEF_CALLBACK browser_process_handler_on_schedule_message_pump_work(
|
||||
struct _cef_browser_process_handler_t* self,
|
||||
int64_t delay_ms) {
|
||||
|
@ -122,6 +149,8 @@ CefBrowserProcessHandlerCppToC::CefBrowserProcessHandlerCppToC() {
|
|||
browser_process_handler_on_context_initialized;
|
||||
GetStruct()->on_before_child_process_launch =
|
||||
browser_process_handler_on_before_child_process_launch;
|
||||
GetStruct()->on_already_running_app_relaunch =
|
||||
browser_process_handler_on_already_running_app_relaunch;
|
||||
GetStruct()->on_schedule_message_pump_work =
|
||||
browser_process_handler_on_schedule_message_pump_work;
|
||||
GetStruct()->get_default_client = browser_process_handler_get_default_client;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=533775387bf1001675aeb94a62bc4ece1eb11125$
|
||||
// $hash=8a552c517824da5047969cf0ef19a9258596e3b9$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/browser_process_handler_ctocpp.h"
|
||||
|
@ -79,6 +79,33 @@ void CefBrowserProcessHandlerCToCpp::OnBeforeChildProcessLaunch(
|
|||
_struct, CefCommandLineCppToC::Wrap(command_line));
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefBrowserProcessHandlerCToCpp::OnAlreadyRunningAppRelaunch(
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) {
|
||||
cef_browser_process_handler_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, on_already_running_app_relaunch)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: command_line; type: refptr_diff
|
||||
DCHECK(command_line.get());
|
||||
if (!command_line.get()) {
|
||||
return false;
|
||||
}
|
||||
// Unverified params: current_directory
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->on_already_running_app_relaunch(
|
||||
_struct, CefCommandLineCppToC::Wrap(command_line),
|
||||
current_directory.GetStruct());
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
void CefBrowserProcessHandlerCToCpp::OnScheduleMessagePumpWork(
|
||||
int64_t delay_ms) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=5dd3fc70331d85a1c7ce5e402bc1e2f050fbe467$
|
||||
// $hash=d70cd8684eceea74a617559d5573b1875392cfaf$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_PROCESS_HANDLER_CTOCPP_H_
|
||||
|
@ -41,6 +41,8 @@ class CefBrowserProcessHandlerCToCpp
|
|||
void OnContextInitialized() override;
|
||||
void OnBeforeChildProcessLaunch(
|
||||
CefRefPtr<CefCommandLine> command_line) override;
|
||||
bool OnAlreadyRunningAppRelaunch(CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) override;
|
||||
void OnScheduleMessagePumpWork(int64_t delay_ms) override;
|
||||
CefRefPtr<CefClient> GetDefaultClient() override;
|
||||
};
|
||||
|
|
|
@ -279,6 +279,11 @@ patches = [
|
|||
# https://github.com/chromiumembedded/cef/issues/3581
|
||||
'name': 'chrome_browser_policy',
|
||||
},
|
||||
{
|
||||
# Support override of Chrome process singleton behavior.
|
||||
# https://github.com/chromiumembedded/cef/issues/3609
|
||||
'name': 'chrome_browser_startup',
|
||||
},
|
||||
{
|
||||
# alloy: Don't initialize ExtensionSystemFactory when extensions are
|
||||
# disabled.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
|
||||
index bce36d7ffb408..33fdb680fb20a 100644
|
||||
index bce36d7ffb408..3e8fd566a375c 100644
|
||||
--- chrome/browser/BUILD.gn
|
||||
+++ chrome/browser/BUILD.gn
|
||||
@@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni")
|
||||
|
@ -10,17 +10,7 @@ index bce36d7ffb408..33fdb680fb20a 100644
|
|||
import("//chrome/browser/buildflags.gni")
|
||||
import("//chrome/browser/downgrade/buildflags.gni")
|
||||
import("//chrome/common/features.gni")
|
||||
@@ -110,7 +111,8 @@ buildflag_header("buildflags") {
|
||||
|
||||
# Android and ChromeOS don't support multiple browser processes, so they don't
|
||||
# employ ProcessSingleton.
|
||||
- if (is_android || is_chromeos) {
|
||||
+ # Also disable for CEF (see issue #3609).
|
||||
+ if (is_android || is_chromeos || enable_cef) {
|
||||
flags += [ "ENABLE_PROCESS_SINGLETON=0" ]
|
||||
} else {
|
||||
flags += [ "ENABLE_PROCESS_SINGLETON=1" ]
|
||||
@@ -2073,6 +2075,7 @@ static_library("browser") {
|
||||
@@ -2073,6 +2074,7 @@ static_library("browser") {
|
||||
"//build/config/chromebox_for_meetings:buildflags",
|
||||
"//build/config/compiler:compiler_buildflags",
|
||||
"//cc",
|
||||
|
@ -28,7 +18,7 @@ index bce36d7ffb408..33fdb680fb20a 100644
|
|||
"//chrome:extra_resources",
|
||||
"//chrome:resources",
|
||||
"//chrome:strings",
|
||||
@@ -2729,6 +2732,10 @@ static_library("browser") {
|
||||
@@ -2729,6 +2731,10 @@ static_library("browser") {
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -39,37 +29,3 @@ index bce36d7ffb408..33fdb680fb20a 100644
|
|||
if (is_android) {
|
||||
sources += [
|
||||
"accessibility/accessibility_prefs/android/accessibility_prefs_controller.cc",
|
||||
diff --git chrome/browser/browser_process_platform_part_win.cc chrome/browser/browser_process_platform_part_win.cc
|
||||
index 66fa1aa8b10b3..9b506f6d153ae 100644
|
||||
--- chrome/browser/browser_process_platform_part_win.cc
|
||||
+++ chrome/browser/browser_process_platform_part_win.cc
|
||||
@@ -9,6 +9,7 @@
|
||||
BrowserProcessPlatformPart::BrowserProcessPlatformPart() = default;
|
||||
BrowserProcessPlatformPart::~BrowserProcessPlatformPart() = default;
|
||||
|
||||
+#if BUILDFLAG(ENABLE_PROCESS_SINGLETON)
|
||||
void BrowserProcessPlatformPart::OnBrowserLaunch() {
|
||||
if constexpr (kShouldRecordActiveUse) {
|
||||
if (!did_run_updater_) {
|
||||
@@ -16,3 +17,4 @@ void BrowserProcessPlatformPart::OnBrowserLaunch() {
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif // BUILDFLAG(ENABLE_PROCESS_SINGLETON)
|
||||
diff --git chrome/browser/browser_process_platform_part_win.h chrome/browser/browser_process_platform_part_win.h
|
||||
index fc4b9808f3f6e..92cef9459811f 100644
|
||||
--- chrome/browser/browser_process_platform_part_win.h
|
||||
+++ chrome/browser/browser_process_platform_part_win.h
|
||||
@@ -18,10 +18,12 @@ class BrowserProcessPlatformPart : public BrowserProcessPlatformPartBase {
|
||||
~BrowserProcessPlatformPart() override;
|
||||
|
||||
// BrowserProcessPlatformPartBase:
|
||||
+#if BUILDFLAG(ENABLE_PROCESS_SINGLETON)
|
||||
void OnBrowserLaunch() override;
|
||||
|
||||
private:
|
||||
absl::optional<DidRunUpdater> did_run_updater_;
|
||||
+#endif // BUILDFLAG(ENABLE_PROCESS_SINGLETON)
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_WIN_H_
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
diff --git chrome/browser/ui/startup/startup_browser_creator.cc chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
index cef85a137d3e2..985d716ec7549 100644
|
||||
--- chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
+++ chrome/browser/ui/startup/startup_browser_creator.cc
|
||||
@@ -578,6 +578,14 @@ void OpenNewWindowForFirstRun(
|
||||
is_first_run, std::move(launch_mode_recorder));
|
||||
}
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT)
|
||||
+
|
||||
+StartupBrowserCreator::ProcessCommandLineCallback*
|
||||
+GetProcessCommandLineCallback() {
|
||||
+ static base::NoDestructor<StartupBrowserCreator::ProcessCommandLineCallback>
|
||||
+ callback;
|
||||
+ return callback.get();
|
||||
+}
|
||||
+
|
||||
} // namespace
|
||||
|
||||
StartupProfileMode StartupProfileModeFromReason(
|
||||
@@ -1441,6 +1449,12 @@ void StartupBrowserCreator::ProcessCommandLineWithProfile(
|
||||
{profile, mode}, last_opened_profiles);
|
||||
}
|
||||
|
||||
+// static
|
||||
+void StartupBrowserCreator::RegisterProcessCommandLineCallback(
|
||||
+ ProcessCommandLineCallback cb) {
|
||||
+ *GetProcessCommandLineCallback() = cb;
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
|
||||
const base::CommandLine& command_line,
|
||||
@@ -1450,6 +1464,11 @@ void StartupBrowserCreator::ProcessCommandLineAlreadyRunning(
|
||||
return;
|
||||
}
|
||||
|
||||
+ auto* cb = GetProcessCommandLineCallback();
|
||||
+ if (!cb->is_null() && cb->Run(command_line, cur_dir)) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
Profile* profile = nullptr;
|
||||
StartupProfileMode mode =
|
||||
StartupProfileModeFromReason(profile_path_info.reason);
|
||||
diff --git chrome/browser/ui/startup/startup_browser_creator.h chrome/browser/ui/startup/startup_browser_creator.h
|
||||
index e22ea9b782910..68724228e79f5 100644
|
||||
--- chrome/browser/ui/startup/startup_browser_creator.h
|
||||
+++ chrome/browser/ui/startup/startup_browser_creator.h
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
+#include "base/functional/callback.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "build/build_config.h"
|
||||
@@ -136,6 +137,13 @@ class StartupBrowserCreator {
|
||||
StartupProfileInfo profile_info,
|
||||
const Profiles& last_opened_profiles);
|
||||
|
||||
+ // Registers a callback that will be executed each time
|
||||
+ // ProcessCommandLineAlreadyRunning is called.
|
||||
+ using ProcessCommandLineCallback = base::RepeatingCallback<bool(
|
||||
+ const base::CommandLine& command_line,
|
||||
+ const base::FilePath& cur_dir)>;
|
||||
+ static void RegisterProcessCommandLineCallback(ProcessCommandLineCallback cb);
|
||||
+
|
||||
// This function performs command-line handling and is invoked only after
|
||||
// start up (for example when we get a start request for another process).
|
||||
// |command_line| holds the command line we need to process.
|
|
@ -1,5 +1,5 @@
|
|||
diff --git chrome/app/chrome_main_delegate.cc chrome/app/chrome_main_delegate.cc
|
||||
index dc84cbd4c97d1..b8a1dd5a19be1 100644
|
||||
index dc84cbd4c97d1..696af79e6cec5 100644
|
||||
--- chrome/app/chrome_main_delegate.cc
|
||||
+++ chrome/app/chrome_main_delegate.cc
|
||||
@@ -41,6 +41,7 @@
|
||||
|
@ -30,6 +30,15 @@ index dc84cbd4c97d1..b8a1dd5a19be1 100644
|
|||
absl::optional<int> ChromeMainDelegate::PostEarlyInitialization(
|
||||
InvokedIn invoked_in) {
|
||||
DCHECK(base::ThreadPoolInstance::Get());
|
||||
@@ -782,7 +789,7 @@ absl::optional<int> ChromeMainDelegate::PostEarlyInitialization(
|
||||
// future session's metrics.
|
||||
DeferBrowserMetrics(user_data_dir);
|
||||
|
||||
-#if BUILDFLAG(IS_WIN)
|
||||
+#if BUILDFLAG(IS_WIN) && !BUILDFLAG(ENABLE_CEF)
|
||||
// In the case the process is not the singleton process, the uninstall tasks
|
||||
// need to be executed here. A window will be displayed asking to close all
|
||||
// running instances.
|
||||
@@ -946,7 +953,8 @@ absl::optional<int> ChromeMainDelegate::PostEarlyInitialization(
|
||||
|
||||
if (base::FeatureList::IsEnabled(
|
||||
|
@ -126,7 +135,7 @@ index 176b6248f18e8..1360e8c209eba 100644
|
|||
#if BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
std::unique_ptr<chromeos::LacrosService> lacros_service_;
|
||||
diff --git chrome/browser/chrome_browser_main.cc chrome/browser/chrome_browser_main.cc
|
||||
index e819129536dc0..d0f1e684ae019 100644
|
||||
index e819129536dc0..e9287f6e03a88 100644
|
||||
--- chrome/browser/chrome_browser_main.cc
|
||||
+++ chrome/browser/chrome_browser_main.cc
|
||||
@@ -52,6 +52,7 @@
|
||||
|
@ -137,6 +146,15 @@ index e819129536dc0..d0f1e684ae019 100644
|
|||
#include "chrome/browser/about_flags.h"
|
||||
#include "chrome/browser/active_use_util.h"
|
||||
#include "chrome/browser/after_startup_task_utils.h"
|
||||
@@ -486,7 +487,7 @@ void ProcessSingletonNotificationCallbackImpl(
|
||||
return;
|
||||
}
|
||||
|
||||
-#if BUILDFLAG(IS_WIN)
|
||||
+#if BUILDFLAG(IS_WIN) && !BUILDFLAG(ENABLE_CEF)
|
||||
// The uninstall command-line switch is handled by the origin process; see
|
||||
// ChromeMainDelegate::PostEarlyInitialization(...). The other process won't
|
||||
// be able to become the singleton process and will display a window asking
|
||||
@@ -774,7 +775,7 @@ int ChromeBrowserMainParts::PreEarlyInitialization() {
|
||||
return content::RESULT_CODE_NORMAL_EXIT;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "include/cef_file_util.h"
|
||||
#include "tests/cefclient/browser/client_prefs.h"
|
||||
#include "tests/cefclient/browser/default_client_handler.h"
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
#include "tests/cefclient/browser/root_window_manager.h"
|
||||
#include "tests/shared/common/client_switches.h"
|
||||
|
||||
namespace client {
|
||||
|
@ -62,6 +64,20 @@ class ClientBrowserDelegate : public ClientAppBrowser::Delegate {
|
|||
}
|
||||
}
|
||||
|
||||
bool OnAlreadyRunningAppRelaunch(
|
||||
CefRefPtr<ClientAppBrowser> app,
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) override {
|
||||
// Create a new root window based on |command_line|.
|
||||
auto config = std::make_unique<RootWindowConfig>(command_line->Copy());
|
||||
|
||||
MainContext::Get()->GetRootWindowManager()->CreateRootWindow(
|
||||
std::move(config));
|
||||
|
||||
// Relaunch was handled.
|
||||
return true;
|
||||
}
|
||||
|
||||
CefRefPtr<CefClient> GetDefaultClient(
|
||||
CefRefPtr<ClientAppBrowser> app) override {
|
||||
// Default client handler for unmanaged browser windows. Used with the
|
||||
|
|
|
@ -1423,12 +1423,15 @@ bool ClientHandler::CreatePopupWindow(CefRefPtr<CefBrowser> browser,
|
|||
CefBrowserSettings& settings) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
auto parent_window = RootWindow::GetForBrowser(browser->GetIdentifier());
|
||||
CHECK(parent_window);
|
||||
|
||||
// The popup browser will be parented to a new native window.
|
||||
// Don't show URL bar and navigation buttons on DevTools windows.
|
||||
// May return nullptr if UseDefaultPopup() returns true.
|
||||
return !!MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||
with_controls_ && !is_devtools, is_osr_, popupFeatures, windowInfo,
|
||||
client, settings);
|
||||
parent_window, with_controls_ && !is_devtools, is_osr_, popupFeatures,
|
||||
windowInfo, client, settings);
|
||||
}
|
||||
|
||||
void ClientHandler::NotifyBrowserCreated(CefRefPtr<CefBrowser> browser) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "include/base/cef_macros.h"
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/internal/cef_types_wrappers.h"
|
||||
#include "tests/cefclient/browser/osr_renderer_settings.h"
|
||||
|
||||
|
@ -24,6 +25,9 @@ class MainContext {
|
|||
// Returns the singleton instance of this object.
|
||||
static MainContext* Get();
|
||||
|
||||
// Returns the global command-line.
|
||||
virtual CefRefPtr<CefCommandLine> GetCommandLine() = 0;
|
||||
|
||||
// Returns the full path to the console log file.
|
||||
virtual std::string GetConsoleLogPath() = 0;
|
||||
|
||||
|
@ -33,8 +37,8 @@ class MainContext {
|
|||
// Returns the app working directory including trailing path separator.
|
||||
virtual std::string GetAppWorkingDirectory() = 0;
|
||||
|
||||
// Returns the main application URL.
|
||||
virtual std::string GetMainURL() = 0;
|
||||
// Returns the main application URL based on |command_line| and global state.
|
||||
virtual std::string GetMainURL(CefRefPtr<CefCommandLine> command_line) = 0;
|
||||
|
||||
// Returns the background color.
|
||||
virtual cef_color_t GetBackgroundColor() = 0;
|
||||
|
|
|
@ -46,14 +46,6 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
|
|||
terminate_when_all_windows_closed_(terminate_when_all_windows_closed) {
|
||||
DCHECK(command_line_.get());
|
||||
|
||||
// Set the main URL.
|
||||
if (command_line_->HasSwitch(switches::kUrl)) {
|
||||
main_url_ = command_line_->GetSwitchValue(switches::kUrl);
|
||||
}
|
||||
if (main_url_.empty()) {
|
||||
main_url_ = kDefaultUrl;
|
||||
}
|
||||
|
||||
// Whether windowless (off-screen) rendering will be used.
|
||||
use_windowless_rendering_ =
|
||||
command_line_->HasSwitch(switches::kOffScreenRenderingEnabled);
|
||||
|
@ -127,12 +119,6 @@ MainContextImpl::MainContextImpl(CefRefPtr<CefCommandLine> command_line,
|
|||
}
|
||||
#endif // !(defined(OS_WIN) || defined(OS_LINUX))
|
||||
|
||||
if (use_views_ && command_line->HasSwitch(switches::kHideFrame) &&
|
||||
!command_line_->HasSwitch(switches::kUrl)) {
|
||||
// Use the draggable regions test as the default URL for frameless windows.
|
||||
main_url_ = test_runner::GetTestURL("draggable");
|
||||
}
|
||||
|
||||
if (command_line_->HasSwitch(switches::kBackgroundColor)) {
|
||||
// Parse the background color value.
|
||||
background_color_ =
|
||||
|
@ -159,12 +145,28 @@ MainContextImpl::~MainContextImpl() {
|
|||
DCHECK(!initialized_ || shutdown_);
|
||||
}
|
||||
|
||||
CefRefPtr<CefCommandLine> MainContextImpl::GetCommandLine() {
|
||||
return command_line_;
|
||||
}
|
||||
|
||||
std::string MainContextImpl::GetConsoleLogPath() {
|
||||
return GetAppWorkingDirectory() + "console.log";
|
||||
}
|
||||
|
||||
std::string MainContextImpl::GetMainURL() {
|
||||
return main_url_;
|
||||
std::string MainContextImpl::GetMainURL(
|
||||
CefRefPtr<CefCommandLine> command_line) {
|
||||
if (!command_line) {
|
||||
command_line = command_line_;
|
||||
}
|
||||
|
||||
std::string main_url = kDefaultUrl;
|
||||
if (command_line->HasSwitch(switches::kUrl)) {
|
||||
main_url = command_line->GetSwitchValue(switches::kUrl);
|
||||
} else if (use_views_ && command_line->HasSwitch(switches::kHideFrame)) {
|
||||
// Use the draggable regions test as the default URL for frameless windows.
|
||||
main_url = test_runner::GetTestURL("draggable");
|
||||
}
|
||||
return main_url;
|
||||
}
|
||||
|
||||
cef_color_t MainContextImpl::GetBackgroundColor() {
|
||||
|
|
|
@ -23,10 +23,11 @@ class MainContextImpl : public MainContext {
|
|||
bool terminate_when_all_windows_closed);
|
||||
|
||||
// MainContext members.
|
||||
CefRefPtr<CefCommandLine> GetCommandLine() override;
|
||||
std::string GetConsoleLogPath() override;
|
||||
std::string GetDownloadPath(const std::string& file_name) override;
|
||||
std::string GetAppWorkingDirectory() override;
|
||||
std::string GetMainURL() override;
|
||||
std::string GetMainURL(CefRefPtr<CefCommandLine> command_line) override;
|
||||
cef_color_t GetBackgroundColor() override;
|
||||
bool UseChromeRuntime() override;
|
||||
bool UseChromeRuntimeNative() override;
|
||||
|
@ -69,7 +70,6 @@ class MainContextImpl : public MainContext {
|
|||
bool initialized_ = false;
|
||||
bool shutdown_ = false;
|
||||
|
||||
std::string main_url_;
|
||||
cef_color_t background_color_ = 0;
|
||||
cef_color_t browser_background_color_ = 0;
|
||||
bool use_windowless_rendering_;
|
||||
|
|
|
@ -8,10 +8,14 @@
|
|||
|
||||
#include "tests/cefclient/browser/main_context.h"
|
||||
#include "tests/cefclient/browser/root_window_manager.h"
|
||||
#include "tests/shared/common/client_switches.h"
|
||||
|
||||
namespace client {
|
||||
|
||||
RootWindowConfig::RootWindowConfig() : url(MainContext::Get()->GetMainURL()) {}
|
||||
RootWindowConfig::RootWindowConfig(CefRefPtr<CefCommandLine> cmd)
|
||||
: command_line(cmd ? cmd : MainContext::Get()->GetCommandLine()),
|
||||
with_controls(!command_line->HasSwitch(switches::kHideControls)),
|
||||
url(MainContext::Get()->GetMainURL(command_line)) {}
|
||||
|
||||
RootWindow::RootWindow() : delegate_(nullptr) {}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "include/base/cef_callback_forward.h"
|
||||
#include "include/base/cef_ref_counted.h"
|
||||
#include "include/cef_browser.h"
|
||||
#include "include/cef_command_line.h"
|
||||
#include "include/views/cef_window.h"
|
||||
#include "tests/cefclient/browser/client_types.h"
|
||||
#include "tests/cefclient/browser/image_cache.h"
|
||||
|
@ -35,7 +36,13 @@ enum class WindowType {
|
|||
|
||||
// Used to configure how a RootWindow is created.
|
||||
struct RootWindowConfig {
|
||||
RootWindowConfig();
|
||||
// |command_line| will be non-nullptr when used for new window creation
|
||||
// via OnAlreadyRunningAppRelaunch (chrome runtime only). Otherwise, the
|
||||
// global command-line will be used.
|
||||
RootWindowConfig(CefRefPtr<CefCommandLine> command_line = nullptr);
|
||||
|
||||
// Associated command-line.
|
||||
CefRefPtr<CefCommandLine> command_line;
|
||||
|
||||
// Configure the window type.
|
||||
WindowType window_type = WindowType::NORMAL;
|
||||
|
@ -59,18 +66,18 @@ struct RootWindowConfig {
|
|||
// Position of the UI element that triggered the window creation. If |bounds|
|
||||
// is empty and |source_bounds| is non-empty the new window will be positioned
|
||||
// relative to |source_bounds|. This is currently only implemented for Views-
|
||||
// based windows when |initially_hidden| is also true.
|
||||
// hosted windows when |initially_hidden| is also true.
|
||||
CefRect source_bounds;
|
||||
|
||||
// Requested window show state. Only used when |bounds| is non-empty and
|
||||
// |initially_hidden| is false.
|
||||
cef_show_state_t show_state = CEF_SHOW_STATE_NORMAL;
|
||||
|
||||
// Parent window. Only used for Views-based windows.
|
||||
// Parent window. Only used for Views-hosted windows.
|
||||
CefRefPtr<CefWindow> parent_window;
|
||||
|
||||
// Callback to be executed when the window is closed. Will be executed on the
|
||||
// main thread. This is currently only implemented for Views-based windows.
|
||||
// main thread. This is currently only implemented for Views-hosted windows.
|
||||
base::OnceClosure close_callback;
|
||||
|
||||
// Initial URL to load.
|
||||
|
@ -128,13 +135,19 @@ class RootWindow
|
|||
// Create a new RootWindow object. This method may be called on any thread.
|
||||
// Use RootWindowManager::CreateRootWindow() or CreateRootWindowAsPopup()
|
||||
// instead of calling this method directly. |use_views| will be true if the
|
||||
// Views framework should be used.
|
||||
static scoped_refptr<RootWindow> Create(bool use_views);
|
||||
// Views framework should be used. |parent_window| will be non-nullptr for
|
||||
// popup browsers with a RootWindow parent (on the UI thread only).
|
||||
static scoped_refptr<RootWindow> Create(
|
||||
bool use_views,
|
||||
scoped_refptr<RootWindow> parent_window);
|
||||
|
||||
// Returns the RootWindow associated with the specified |browser_id|. Must be
|
||||
// called on the main thread.
|
||||
static scoped_refptr<RootWindow> GetForBrowser(int browser_id);
|
||||
|
||||
// Returns true if the RootWindow is Views-hosted.
|
||||
virtual bool IsViewsHosted() const { return false; }
|
||||
|
||||
// Initialize as a normal window. This will create and show a native window
|
||||
// hosting a single browser instance. This method may be called on any thread.
|
||||
// |delegate| must be non-nullptr and outlive this object.
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
namespace client {
|
||||
|
||||
// static
|
||||
scoped_refptr<RootWindow> RootWindow::Create(bool use_views) {
|
||||
scoped_refptr<RootWindow> RootWindow::Create(
|
||||
bool use_views,
|
||||
scoped_refptr<RootWindow> parent_window) {
|
||||
if (use_views) {
|
||||
return new RootWindowViews();
|
||||
CHECK(!parent_window || parent_window->IsViewsHosted());
|
||||
return new RootWindowViews(
|
||||
static_cast<RootWindowViews*>(parent_window.get()));
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
|
|
@ -62,7 +62,8 @@ class ClientRequestContextHandler : public CefRequestContextHandler,
|
|||
// Allow the startup URL to create popups that bypass the popup blocker.
|
||||
// For example, via Tests > New Popup from the top menu. This applies for
|
||||
// for the Chrome runtime only.
|
||||
const auto& startup_url = MainContext::Get()->GetMainURL();
|
||||
const auto& startup_url =
|
||||
MainContext::Get()->GetMainURL(/*command_line=*/nullptr);
|
||||
request_context->SetContentSetting(startup_url, startup_url,
|
||||
CEF_CONTENT_SETTING_TYPE_POPUPS,
|
||||
CEF_CONTENT_SETTING_VALUE_ALLOW);
|
||||
|
@ -121,8 +122,8 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindow(
|
|||
CefBrowserSettings settings;
|
||||
MainContext::Get()->PopulateBrowserSettings(&settings);
|
||||
|
||||
scoped_refptr<RootWindow> root_window =
|
||||
RootWindow::Create(MainContext::Get()->UseViews());
|
||||
scoped_refptr<RootWindow> root_window = RootWindow::Create(
|
||||
MainContext::Get()->UseViews(), /*parent_window=*/nullptr);
|
||||
root_window->Init(this, std::move(config), settings);
|
||||
|
||||
// Store a reference to the root window on the main thread.
|
||||
|
@ -132,6 +133,7 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindow(
|
|||
}
|
||||
|
||||
scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
||||
scoped_refptr<RootWindow> parent_window,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
|
@ -155,8 +157,11 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||
temp_window_.reset(new TempWindow());
|
||||
}
|
||||
|
||||
const bool use_views = parent_window ? parent_window->IsViewsHosted()
|
||||
: MainContext::Get()->UseViews();
|
||||
|
||||
scoped_refptr<RootWindow> root_window =
|
||||
RootWindow::Create(MainContext::Get()->UseViews());
|
||||
RootWindow::Create(use_views, parent_window);
|
||||
root_window->InitAsPopup(this, with_controls, with_osr, popupFeatures,
|
||||
windowInfo, client, settings);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ class RootWindowManager : public RootWindow::Delegate {
|
|||
// This method is called from ClientHandler::CreatePopupWindow() to
|
||||
// create a new popup or DevTools window. Must be called on the UI thread.
|
||||
scoped_refptr<RootWindow> CreateRootWindowAsPopup(
|
||||
scoped_refptr<RootWindow> parent_window,
|
||||
bool with_controls,
|
||||
bool with_osr,
|
||||
const CefPopupFeatures& popupFeatures,
|
||||
|
|
|
@ -22,7 +22,17 @@ static const char* kDefaultImageCache[] = {"menu_icon", "window_icon"};
|
|||
|
||||
} // namespace
|
||||
|
||||
RootWindowViews::RootWindowViews() = default;
|
||||
RootWindowViews::RootWindowViews(RootWindowViews* parent_window) {
|
||||
// |parent_window| will be non-nullptr for popups only.
|
||||
if (parent_window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
// Initialize |config_| for values that are not passed to InitAsPopup().
|
||||
config_ = std::make_unique<RootWindowConfig>(
|
||||
parent_window->config_->command_line);
|
||||
DCHECK(config_->command_line);
|
||||
}
|
||||
}
|
||||
|
||||
RootWindowViews::~RootWindowViews() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
|
@ -38,6 +48,7 @@ void RootWindowViews::Init(RootWindow::Delegate* delegate,
|
|||
std::unique_ptr<RootWindowConfig> config,
|
||||
const CefBrowserSettings& settings) {
|
||||
DCHECK(delegate);
|
||||
DCHECK(config->command_line);
|
||||
DCHECK(!config->with_osr); // Windowless rendering is not supported.
|
||||
DCHECK(!initialized_);
|
||||
|
||||
|
@ -65,7 +76,9 @@ void RootWindowViews::InitAsPopup(RootWindow::Delegate* delegate,
|
|||
DCHECK(!initialized_);
|
||||
|
||||
delegate_ = delegate;
|
||||
config_ = std::make_unique<RootWindowConfig>();
|
||||
|
||||
// |config_| should be created in the constructor.
|
||||
DCHECK(config_);
|
||||
config_->with_controls = with_controls;
|
||||
|
||||
if (popupFeatures.xSet) {
|
||||
|
@ -556,7 +569,7 @@ void RootWindowViews::CreateViewsWindow(
|
|||
|
||||
// Create the ViewsWindow. It will show itself after creation.
|
||||
ViewsWindow::Create(config_->window_type, this, client_handler_, config_->url,
|
||||
settings, request_context);
|
||||
settings, request_context, config_->command_line);
|
||||
}
|
||||
|
||||
void RootWindowViews::NotifyViewsWindowDestroyed() {
|
||||
|
|
|
@ -22,13 +22,16 @@ class RootWindowViews : public RootWindow,
|
|||
public ClientHandler::Delegate,
|
||||
public ViewsWindow::Delegate {
|
||||
public:
|
||||
// Constructor may be called on any thread.
|
||||
RootWindowViews();
|
||||
// Constructor may be called on any thread. |parent_window| will be
|
||||
// non-nullptr for popup browsers with a RootWindow parent (called on the UI
|
||||
// thread only).
|
||||
explicit RootWindowViews(RootWindowViews* parent_window);
|
||||
~RootWindowViews();
|
||||
|
||||
void SetTitlebarHeight(const std::optional<float>& height);
|
||||
|
||||
// RootWindow methods:
|
||||
bool IsViewsHosted() const override { return true; }
|
||||
void Init(RootWindow::Delegate* delegate,
|
||||
std::unique_ptr<RootWindowConfig> config,
|
||||
const CefBrowserSettings& settings) override;
|
||||
|
|
|
@ -137,13 +137,14 @@ CefRefPtr<ViewsWindow> ViewsWindow::Create(
|
|||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context) {
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefCommandLine> command_line) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(delegate);
|
||||
|
||||
// Create a new ViewsWindow.
|
||||
CefRefPtr<ViewsWindow> views_window =
|
||||
new ViewsWindow(type, delegate, nullptr);
|
||||
new ViewsWindow(type, delegate, nullptr, command_line);
|
||||
|
||||
// Create a new BrowserView.
|
||||
CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
|
||||
|
@ -473,7 +474,7 @@ CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
|
|||
// Create a new ViewsWindow for the popup BrowserView.
|
||||
return new ViewsWindow(
|
||||
is_devtools ? WindowType::DEVTOOLS : WindowType::NORMAL, popup_delegate,
|
||||
nullptr);
|
||||
nullptr, command_line_);
|
||||
}
|
||||
|
||||
bool ViewsWindow::OnPopupBrowserViewCreated(
|
||||
|
@ -1037,19 +1038,19 @@ void ViewsWindow::MenuBarExecuteCommand(CefRefPtr<CefMenuModel> menu_model,
|
|||
|
||||
ViewsWindow::ViewsWindow(WindowType type,
|
||||
Delegate* delegate,
|
||||
CefRefPtr<CefBrowserView> browser_view)
|
||||
CefRefPtr<CefBrowserView> browser_view,
|
||||
CefRefPtr<CefCommandLine> command_line)
|
||||
: type_(type),
|
||||
delegate_(delegate),
|
||||
command_line_(command_line),
|
||||
menu_has_focus_(false),
|
||||
last_focused_view_(false) {
|
||||
DCHECK(delegate_);
|
||||
|
||||
if (browser_view) {
|
||||
SetBrowserView(browser_view);
|
||||
}
|
||||
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
|
||||
const bool is_normal_type = type_ == WindowType::NORMAL;
|
||||
|
||||
with_controls_ = is_normal_type && delegate_->WithControls();
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace client {
|
|||
typedef std::set<CefRefPtr<CefExtension>> ExtensionSet;
|
||||
|
||||
// Implements a CefWindow that hosts a single CefBrowserView and optional
|
||||
// Views-based controls. All methods must be called on the browser process UI
|
||||
// Views-hosted controls. All methods must be called on the browser process UI
|
||||
// thread.
|
||||
class ViewsWindow : public CefBrowserViewDelegate,
|
||||
public CefMenuButtonDelegate,
|
||||
|
@ -105,7 +105,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||
CefRefPtr<CefClient> client,
|
||||
const CefString& url,
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefRequestContext> request_context);
|
||||
CefRefPtr<CefRequestContext> request_context,
|
||||
CefRefPtr<CefCommandLine> command_line);
|
||||
|
||||
void Show();
|
||||
void Hide();
|
||||
|
@ -213,7 +214,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||
// called.
|
||||
ViewsWindow(WindowType type,
|
||||
Delegate* delegate,
|
||||
CefRefPtr<CefBrowserView> browser_view);
|
||||
CefRefPtr<CefBrowserView> browser_view,
|
||||
CefRefPtr<CefCommandLine> command_line);
|
||||
|
||||
void SetBrowserView(CefRefPtr<CefBrowserView> browser_view);
|
||||
|
||||
|
@ -254,6 +256,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||
const WindowType type_;
|
||||
Delegate* delegate_; // Not owned by this object.
|
||||
CefRefPtr<CefBrowserView> browser_view_;
|
||||
CefRefPtr<CefCommandLine> command_line_;
|
||||
bool frameless_;
|
||||
bool with_controls_;
|
||||
bool with_overlay_controls_;
|
||||
|
|
|
@ -115,8 +115,12 @@ int RunMain(int argc, char* argv[]) {
|
|||
message_loop.reset(new MainMessageLoopStd);
|
||||
}
|
||||
|
||||
// Initialize CEF.
|
||||
context->Initialize(main_args, settings, app, nullptr);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, nullptr)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Force Gtk to use Xwayland (in case a Wayland compositor is being used).
|
||||
gdk_set_allowed_backends("x11");
|
||||
|
@ -140,8 +144,6 @@ int RunMain(int argc, char* argv[]) {
|
|||
auto window_config = std::make_unique<RootWindowConfig>();
|
||||
window_config->always_on_top =
|
||||
command_line->HasSwitch(switches::kAlwaysOnTop);
|
||||
window_config->with_controls =
|
||||
!command_line->HasSwitch(switches::kHideControls);
|
||||
window_config->with_osr =
|
||||
settings.windowless_rendering_enabled ? true : false;
|
||||
|
||||
|
|
|
@ -52,11 +52,10 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||
// Receives notifications from the application. Will delete itself when done.
|
||||
@interface ClientAppDelegate : NSObject <NSApplicationDelegate> {
|
||||
@private
|
||||
bool with_controls_;
|
||||
bool with_osr_;
|
||||
}
|
||||
|
||||
- (id)initWithControls:(bool)with_controls andOsr:(bool)with_osr;
|
||||
- (id)initWithOsr:(bool)with_osr;
|
||||
- (void)createApplication:(id)object;
|
||||
- (void)tryToTerminateApplication:(NSApplication*)app;
|
||||
- (void)testsItemSelected:(int)command_id;
|
||||
|
@ -162,9 +161,8 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||
|
||||
@implementation ClientAppDelegate
|
||||
|
||||
- (id)initWithControls:(bool)with_controls andOsr:(bool)with_osr {
|
||||
- (id)initWithOsr:(bool)with_osr {
|
||||
if (self = [super init]) {
|
||||
with_controls_ = with_controls;
|
||||
with_osr_ = with_osr;
|
||||
}
|
||||
return self;
|
||||
|
@ -230,7 +228,6 @@ void RemoveMenuItem(NSMenu* menu, SEL action_selector) {
|
|||
}
|
||||
|
||||
auto window_config = std::make_unique<client::RootWindowConfig>();
|
||||
window_config->with_controls = with_controls_;
|
||||
window_config->with_osr = with_osr_;
|
||||
|
||||
// Create the first window.
|
||||
|
@ -570,16 +567,19 @@ int RunMain(int argc, char* argv[]) {
|
|||
message_loop.reset(new MainMessageLoopStd);
|
||||
}
|
||||
|
||||
// Initialize CEF.
|
||||
context->Initialize(main_args, settings, app, nullptr);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, nullptr)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
|
||||
// Create the application delegate and window.
|
||||
ClientAppDelegate* delegate = [[ClientAppDelegate alloc]
|
||||
initWithControls:!command_line->HasSwitch(switches::kHideControls)
|
||||
andOsr:settings.windowless_rendering_enabled ? true : false];
|
||||
initWithOsr:settings.windowless_rendering_enabled ? true : false];
|
||||
[delegate performSelectorOnMainThread:@selector(createApplication:)
|
||||
withObject:nil
|
||||
waitUntilDone:NO];
|
||||
|
|
|
@ -95,8 +95,12 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
|||
message_loop.reset(new MainMessageLoopStd);
|
||||
}
|
||||
|
||||
// Initialize CEF.
|
||||
context->Initialize(main_args, settings, app, sandbox_info);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!context->Initialize(main_args, settings, app, sandbox_info)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Register scheme handlers.
|
||||
test_runner::RegisterSchemeHandlers();
|
||||
|
@ -104,8 +108,6 @@ int RunMain(HINSTANCE hInstance, int nCmdShow) {
|
|||
auto window_config = std::make_unique<RootWindowConfig>();
|
||||
window_config->always_on_top =
|
||||
command_line->HasSwitch(switches::kAlwaysOnTop);
|
||||
window_config->with_controls =
|
||||
!command_line->HasSwitch(switches::kHideControls);
|
||||
window_config->with_osr =
|
||||
settings.windowless_rendering_enabled ? true : false;
|
||||
|
||||
|
|
|
@ -77,8 +77,12 @@ int main(int argc, char* argv[]) {
|
|||
// CEF has initialized.
|
||||
CefRefPtr<SimpleApp> app(new SimpleApp);
|
||||
|
||||
// Initialize CEF for the browser process.
|
||||
CefInitialize(main_args, settings, app.get(), nullptr);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), nullptr)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
|
||||
// called.
|
||||
|
|
|
@ -159,8 +159,12 @@ int main(int argc, char* argv[]) {
|
|||
// CEF has initialized.
|
||||
CefRefPtr<SimpleApp> app(new SimpleApp);
|
||||
|
||||
// Initialize CEF for the browser process.
|
||||
CefInitialize(main_args, settings, app.get(), nullptr);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), nullptr)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create the application delegate.
|
||||
NSObject* delegate = [[SimpleAppDelegate alloc] init];
|
||||
|
|
|
@ -88,8 +88,12 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
|||
// CEF has initialized.
|
||||
CefRefPtr<SimpleApp> app(new SimpleApp);
|
||||
|
||||
// Initialize CEF.
|
||||
CefInitialize(main_args, settings, app.get(), sandbox_info);
|
||||
// Initialize the CEF browser process. May return false if initialization
|
||||
// fails or if early exit is desired (for example, due to process singleton
|
||||
// relaunch behavior).
|
||||
if (!CefInitialize(main_args, settings, app.get(), sandbox_info)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
|
||||
// called.
|
||||
|
|
|
@ -31,9 +31,6 @@ namespace {
|
|||
// 4. FrameNavTestHandler retrieves the URL to load via
|
||||
// FrameNavExpectationsBrowser::GetMainURL and calls either CreateBrowser
|
||||
// (for the first navigation) or LoadURL (for the following navigations).
|
||||
// 5. If the renderer process does not already exist CEF creates it with
|
||||
// command-line arguments that specify the FrameNavFactoryId via
|
||||
// FrameNavBrowserTest::OnBeforeChildProcessLaunch.
|
||||
//
|
||||
// In the renderer process:
|
||||
// 6. If the renderer process is newly created FrameNavRendererTest calls
|
||||
|
|
|
@ -94,11 +94,16 @@ void ClientAppBrowser::OnContextInitialized() {
|
|||
}
|
||||
}
|
||||
|
||||
void ClientAppBrowser::OnBeforeChildProcessLaunch(
|
||||
CefRefPtr<CefCommandLine> command_line) {
|
||||
bool ClientAppBrowser::OnAlreadyRunningAppRelaunch(
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) {
|
||||
for (auto& delegate : delegates_) {
|
||||
delegate->OnBeforeChildProcessLaunch(this, command_line);
|
||||
if (delegate->OnAlreadyRunningAppRelaunch(this, command_line,
|
||||
current_directory)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientAppBrowser::OnScheduleMessagePumpWork(int64_t delay) {
|
||||
|
|
|
@ -31,9 +31,12 @@ class ClientAppBrowser : public ClientApp, public CefBrowserProcessHandler {
|
|||
|
||||
virtual void OnContextInitialized(CefRefPtr<ClientAppBrowser> app) {}
|
||||
|
||||
virtual void OnBeforeChildProcessLaunch(
|
||||
virtual bool OnAlreadyRunningAppRelaunch(
|
||||
CefRefPtr<ClientAppBrowser> app,
|
||||
CefRefPtr<CefCommandLine> command_line) {}
|
||||
CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual CefRefPtr<CefClient> GetDefaultClient(
|
||||
CefRefPtr<ClientAppBrowser> app) {
|
||||
|
@ -73,8 +76,8 @@ class ClientAppBrowser : public ClientApp, public CefBrowserProcessHandler {
|
|||
cef_preferences_type_t type,
|
||||
CefRawPtr<CefPreferenceRegistrar> registrar) override;
|
||||
void OnContextInitialized() override;
|
||||
void OnBeforeChildProcessLaunch(
|
||||
CefRefPtr<CefCommandLine> command_line) override;
|
||||
bool OnAlreadyRunningAppRelaunch(CefRefPtr<CefCommandLine> command_line,
|
||||
const CefString& current_directory) override;
|
||||
void OnScheduleMessagePumpWork(int64_t delay) override;
|
||||
CefRefPtr<CefClient> GetDefaultClient() override;
|
||||
|
||||
|
|
Loading…
Reference in New Issue