mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
alloy: Use Chrome JS dialogs on Windows/Linux (fixes issue #3316)
This commit is contained in:
12
BUILD.gn
12
BUILD.gn
@ -420,6 +420,12 @@ static_library("libcef_static") {
|
||||
"libcef/browser/alloy/alloy_web_contents_view_delegate.h",
|
||||
"libcef/browser/alloy/browser_platform_delegate_alloy.cc",
|
||||
"libcef/browser/alloy/browser_platform_delegate_alloy.h",
|
||||
"libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.cc",
|
||||
"libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.h",
|
||||
"libcef/browser/alloy/dialogs/alloy_javascript_dialog_manager_delegate.cc",
|
||||
"libcef/browser/alloy/dialogs/alloy_javascript_dialog_manager_delegate.h",
|
||||
"libcef/browser/alloy/dialogs/alloy_web_contents_dialog_helper.cc",
|
||||
"libcef/browser/alloy/dialogs/alloy_web_contents_dialog_helper.h",
|
||||
"libcef/browser/alloy/chrome_browser_process_alloy.cc",
|
||||
"libcef/browser/alloy/chrome_browser_process_alloy.h",
|
||||
"libcef/browser/alloy/chrome_profile_manager_alloy.cc",
|
||||
@ -655,8 +661,6 @@ static_library("libcef_static") {
|
||||
"libcef/browser/prefs/renderer_prefs.h",
|
||||
"libcef/browser/print_settings_impl.cc",
|
||||
"libcef/browser/print_settings_impl.h",
|
||||
"libcef/browser/printing/constrained_window_views_client.cc",
|
||||
"libcef/browser/printing/constrained_window_views_client.h",
|
||||
"libcef/browser/printing/print_view_manager.cc",
|
||||
"libcef/browser/printing/print_view_manager.h",
|
||||
"libcef/browser/process_util_impl.cc",
|
||||
@ -740,8 +744,6 @@ static_library("libcef_static") {
|
||||
"libcef/browser/views/window_impl.h",
|
||||
"libcef/browser/views/window_view.cc",
|
||||
"libcef/browser/views/window_view.h",
|
||||
"libcef/browser/web_contents_dialog_helper.cc",
|
||||
"libcef/browser/web_contents_dialog_helper.h",
|
||||
"libcef/browser/x509_certificate_impl.cc",
|
||||
"libcef/browser/x509_certificate_impl.h",
|
||||
"libcef/browser/x509_cert_principal_impl.cc",
|
||||
@ -1026,8 +1028,6 @@ static_library("libcef_static") {
|
||||
"libcef/browser/native/browser_platform_delegate_native_win.cc",
|
||||
"libcef/browser/native/browser_platform_delegate_native_win.h",
|
||||
"libcef/browser/native/cursor_util_win.cc",
|
||||
"libcef/browser/native/javascript_dialog_runner_win.cc",
|
||||
"libcef/browser/native/javascript_dialog_runner_win.h",
|
||||
"libcef/browser/osr/browser_platform_delegate_osr_win.cc",
|
||||
"libcef/browser/osr/browser_platform_delegate_osr_win.h",
|
||||
]
|
||||
|
@ -33,7 +33,7 @@
|
||||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=c68332a779bab425aa2e6a858d20a43448631890$
|
||||
// $hash=942579315e4b8c0819cd2b06becb93670310cd09$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_CEF_JSDIALOG_HANDLER_CAPI_H_
|
||||
@ -127,7 +127,7 @@ typedef struct _cef_jsdialog_handler_t {
|
||||
struct _cef_browser_t* browser);
|
||||
|
||||
///
|
||||
// Called when the default implementation dialog is closed.
|
||||
// Called when the dialog is closed.
|
||||
///
|
||||
void(CEF_CALLBACK* on_dialog_closed)(struct _cef_jsdialog_handler_t* self,
|
||||
struct _cef_browser_t* browser);
|
||||
|
@ -118,7 +118,7 @@ class CefJSDialogHandler : public virtual CefBaseRefCounted {
|
||||
virtual void OnResetDialogState(CefRefPtr<CefBrowser> browser) {}
|
||||
|
||||
///
|
||||
// Called when the default implementation dialog is closed.
|
||||
// Called when the dialog is closed.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual void OnDialogClosed(CefRefPtr<CefBrowser> browser) {}
|
||||
|
@ -618,6 +618,14 @@ bool AlloyBrowserHostImpl::IsWindowless() const {
|
||||
return is_windowless_;
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::IsVisible() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (IsWindowless() && platform_delegate_) {
|
||||
return !platform_delegate_->IsHidden();
|
||||
}
|
||||
return CefBrowserHostBase::IsVisible();
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::IsPictureInPictureSupported() const {
|
||||
// Not currently supported with OSR.
|
||||
return !IsWindowless();
|
||||
@ -630,6 +638,11 @@ void AlloyBrowserHostImpl::WindowDestroyed() {
|
||||
CloseBrowser(true);
|
||||
}
|
||||
|
||||
bool AlloyBrowserHostImpl::WillBeDestroyed() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
return destruction_state_ >= DESTRUCTION_STATE_ACCEPTED;
|
||||
}
|
||||
|
||||
void AlloyBrowserHostImpl::DestroyBrowser() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
@ -1233,9 +1246,8 @@ void AlloyBrowserHostImpl::DidNavigatePrimaryMainFramePostCommit(
|
||||
|
||||
content::JavaScriptDialogManager*
|
||||
AlloyBrowserHostImpl::GetJavaScriptDialogManager(content::WebContents* source) {
|
||||
if (!javascript_dialog_manager_.get() && platform_delegate_) {
|
||||
javascript_dialog_manager_.reset(new CefJavaScriptDialogManager(
|
||||
this, platform_delegate_->CreateJavaScriptDialogRunner()));
|
||||
if (!javascript_dialog_manager_) {
|
||||
javascript_dialog_manager_.reset(new CefJavaScriptDialogManager(this));
|
||||
}
|
||||
return javascript_dialog_manager_.get();
|
||||
}
|
||||
|
@ -137,12 +137,16 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
|
||||
// Returns true if windowless rendering is enabled.
|
||||
bool IsWindowless() const override;
|
||||
|
||||
bool IsVisible() const override;
|
||||
|
||||
// Returns true if this browser supports picture-in-picture.
|
||||
bool IsPictureInPictureSupported() const;
|
||||
|
||||
// Called when the OS window hosting the browser is destroyed.
|
||||
void WindowDestroyed() override;
|
||||
|
||||
bool WillBeDestroyed() const override;
|
||||
|
||||
// Destroy the browser members. This method should only be called after the
|
||||
// native browser window is not longer processing messages.
|
||||
void DestroyBrowser() override;
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "libcef/browser/alloy/dialogs/alloy_constrained_window_views_client.h"
|
||||
#include "libcef/browser/browser_context.h"
|
||||
#include "libcef/browser/browser_context_keyed_service_factories.h"
|
||||
#include "libcef/browser/context.h"
|
||||
@ -15,19 +16,21 @@
|
||||
#include "libcef/browser/extensions/extension_system_factory.h"
|
||||
#include "libcef/browser/file_dialog_runner.h"
|
||||
#include "libcef/browser/net/chrome_scheme_handler.h"
|
||||
#include "libcef/browser/printing/constrained_window_views_client.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
#include "libcef/common/app_manager.h"
|
||||
#include "libcef/common/extensions/extensions_util.h"
|
||||
#include "libcef/common/net/net_resource_provider.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "chrome/browser/media/router/chrome_media_router_factory.h"
|
||||
#include "chrome/browser/net/system_network_context_manager.h"
|
||||
#include "chrome/browser/plugins/plugin_finder.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_switches.h"
|
||||
#include "components/constrained_window/constrained_window_views.h"
|
||||
#include "content/public/browser/gpu_data_manager.h"
|
||||
@ -170,7 +173,7 @@ AlloyBrowserMainParts::~AlloyBrowserMainParts() {
|
||||
}
|
||||
|
||||
void AlloyBrowserMainParts::ToolkitInitialized() {
|
||||
SetConstrainedWindowViewsClient(CreateCefConstrainedWindowViewsClient());
|
||||
SetConstrainedWindowViewsClient(CreateAlloyConstrainedWindowViewsClient());
|
||||
#if defined(USE_AURA)
|
||||
CHECK(aura::Env::GetInstance());
|
||||
|
||||
@ -187,6 +190,15 @@ void AlloyBrowserMainParts::ToolkitInitialized() {
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
ToolkitInitializedLinux();
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
if (base::FeatureList::IsEnabled(features::kViewsJSAppModalDialog))
|
||||
InstallChromeJavaScriptAppModalDialogViewFactory();
|
||||
else
|
||||
InstallChromeJavaScriptAppModalDialogViewCocoaFactory();
|
||||
#else
|
||||
InstallChromeJavaScriptAppModalDialogViewFactory();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AlloyBrowserMainParts::PreCreateMainMessageLoop() {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "libcef/browser/alloy/browser_platform_delegate_alloy.h"
|
||||
|
||||
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
|
||||
#include "libcef/browser/alloy/dialogs/alloy_javascript_dialog_manager_delegate.h"
|
||||
#include "libcef/browser/extensions/browser_extensions_util.h"
|
||||
#include "libcef/browser/extensions/extension_background_host.h"
|
||||
#include "libcef/browser/extensions/extension_system.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
|
||||
#include "components/find_in_page/find_tab_helper.h"
|
||||
#include "components/find_in_page/find_types.h"
|
||||
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
|
||||
#include "components/zoom/zoom_controller.h"
|
||||
#include "content/browser/renderer_host/render_widget_host_impl.h"
|
||||
#include "content/browser/web_contents/web_contents_impl.h"
|
||||
@ -184,10 +186,13 @@ void CefBrowserPlatformDelegateAlloy::BrowserCreated(
|
||||
zoom::ZoomController::CreateForWebContents(web_contents_);
|
||||
}
|
||||
|
||||
if (IsPrintPreviewSupported()) {
|
||||
javascript_dialogs::TabModalDialogManager::CreateForWebContents(
|
||||
web_contents_,
|
||||
CreateAlloyJavaScriptTabModalDialogManagerDelegateDesktop(web_contents_));
|
||||
|
||||
// Used for print preview and JavaScript dialogs.
|
||||
web_contents_dialog_helper_.reset(
|
||||
new CefWebContentsDialogHelper(web_contents_, this));
|
||||
}
|
||||
new AlloyWebContentsDialogHelper(web_contents_, this));
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateAlloy::CreateExtensionHost(
|
||||
@ -242,6 +247,11 @@ void CefBrowserPlatformDelegateAlloy::BrowserDestroyed(
|
||||
CefBrowserPlatformDelegate::BrowserDestroyed(browser);
|
||||
}
|
||||
|
||||
web_modal::WebContentsModalDialogHost*
|
||||
CefBrowserPlatformDelegateAlloy::GetWebContentsModalDialogHost() const {
|
||||
return web_contents_dialog_helper_.get();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateAlloy::SendCaptureLostEvent() {
|
||||
if (!web_contents_)
|
||||
return;
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef CEF_LIBCEF_BROWSER_ALLOY_BROWSER_PLATFORM_DELEGATE_ALLOY_H_
|
||||
#define CEF_LIBCEF_BROWSER_ALLOY_BROWSER_PLATFORM_DELEGATE_ALLOY_H_
|
||||
|
||||
#include "libcef/browser/alloy/dialogs/alloy_web_contents_dialog_helper.h"
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
#include "libcef/browser/web_contents_dialog_helper.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "components/find_in_page/find_notification_details.h"
|
||||
@ -42,6 +42,8 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate {
|
||||
extensions::mojom::ViewType host_type) override;
|
||||
extensions::ExtensionHost* GetExtensionHost() const override;
|
||||
void BrowserDestroyed(CefBrowserHostBase* browser) override;
|
||||
web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
|
||||
const override;
|
||||
void SendCaptureLostEvent() override;
|
||||
#if BUILDFLAG(IS_WIN) || (BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC))
|
||||
void NotifyMoveOrResizeStarted() override;
|
||||
@ -98,7 +100,7 @@ class CefBrowserPlatformDelegateAlloy : public CefBrowserPlatformDelegate {
|
||||
std::unique_ptr<content::WebContents> owned_web_contents_;
|
||||
|
||||
// Used for the print preview dialog.
|
||||
std::unique_ptr<CefWebContentsDialogHelper> web_contents_dialog_helper_;
|
||||
std::unique_ptr<AlloyWebContentsDialogHelper> web_contents_dialog_helper_;
|
||||
|
||||
// The last find result. This object contains details about the number of
|
||||
// matches, the find selection rectangle, etc.
|
||||
|
@ -0,0 +1,76 @@
|
||||
// Copyright 2022 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 The Chromium 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/alloy/dialogs/alloy_constrained_window_views_client.h"
|
||||
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "components/web_modal/web_contents_modal_dialog_host.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class AlloyConstrainedWindowViewsClient
|
||||
: public constrained_window::ConstrainedWindowViewsClient {
|
||||
public:
|
||||
AlloyConstrainedWindowViewsClient() = default;
|
||||
|
||||
AlloyConstrainedWindowViewsClient(const AlloyConstrainedWindowViewsClient&) =
|
||||
delete;
|
||||
AlloyConstrainedWindowViewsClient& operator=(
|
||||
const AlloyConstrainedWindowViewsClient&) = delete;
|
||||
|
||||
private:
|
||||
// ConstrainedWindowViewsClient methods:
|
||||
web_modal::ModalDialogHost* GetModalDialogHost(
|
||||
gfx::NativeWindow parent) override {
|
||||
if (auto browser = GetPreferredBrowser(parent)) {
|
||||
return browser->platform_delegate()->GetWebContentsModalDialogHost();
|
||||
}
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::NativeView GetDialogHostView(gfx::NativeWindow parent) override {
|
||||
if (auto dialog_host = GetModalDialogHost(parent)) {
|
||||
return dialog_host->GetHostView();
|
||||
}
|
||||
return gfx::NativeView();
|
||||
}
|
||||
|
||||
static CefRefPtr<CefBrowserHostBase> GetPreferredBrowser(
|
||||
gfx::NativeWindow parent) {
|
||||
CefRefPtr<CefBrowserHostBase> browser;
|
||||
|
||||
// 1. Browser associated with the top-level native window (owning_window).
|
||||
// This should be reliable with windowed browsers. However, |parent| will
|
||||
// always be nullptr with windowless browsers.
|
||||
if (parent) {
|
||||
browser = CefBrowserHostBase::GetBrowserForTopLevelNativeWindow(parent);
|
||||
if (!browser) {
|
||||
LOG(WARNING) << "No browser associated with top-level native window";
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Browser most likely to be focused. This may be somewhat iffy with
|
||||
// windowless browsers as there is no guarantee that the client has only
|
||||
// one browser focused at a time.
|
||||
if (!browser) {
|
||||
browser = CefBrowserHostBase::GetLikelyFocusedBrowser();
|
||||
if (!browser) {
|
||||
LOG(WARNING) << "No likely focused browser";
|
||||
}
|
||||
}
|
||||
|
||||
return browser;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
|
||||
CreateAlloyConstrainedWindowViewsClient() {
|
||||
return std::make_unique<AlloyConstrainedWindowViewsClient>();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
// Copyright 2022 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2014 The Chromium 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_ALLOY_DIALOGS_ALLOY_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
||||
#define CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "components/constrained_window/constrained_window_views_client.h"
|
||||
|
||||
// Creates a ConstrainedWindowViewsClient for the Chrome environment.
|
||||
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
|
||||
CreateAlloyConstrainedWindowViewsClient();
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
@ -0,0 +1,58 @@
|
||||
// Copyright 2022 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright 2020 The Chromium 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/alloy/dialogs/alloy_javascript_dialog_manager_delegate.h"
|
||||
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class AlloyJavaScriptTabModalDialogManagerDelegateDesktop
|
||||
: public JavaScriptTabModalDialogManagerDelegateDesktop {
|
||||
public:
|
||||
explicit AlloyJavaScriptTabModalDialogManagerDelegateDesktop(
|
||||
content::WebContents* web_contents)
|
||||
: JavaScriptTabModalDialogManagerDelegateDesktop(web_contents),
|
||||
web_contents_(web_contents) {}
|
||||
|
||||
AlloyJavaScriptTabModalDialogManagerDelegateDesktop(
|
||||
const AlloyJavaScriptTabModalDialogManagerDelegateDesktop&) = delete;
|
||||
AlloyJavaScriptTabModalDialogManagerDelegateDesktop& operator=(
|
||||
const AlloyJavaScriptTabModalDialogManagerDelegateDesktop&) = delete;
|
||||
|
||||
// javascript_dialogs::TabModalDialogManagerDelegate methods:
|
||||
void WillRunDialog() override {}
|
||||
|
||||
void DidCloseDialog() override {}
|
||||
|
||||
void SetTabNeedsAttention(bool attention) override {}
|
||||
|
||||
bool IsWebContentsForemost() override {
|
||||
if (auto browser =
|
||||
CefBrowserHostBase::GetBrowserForContents(web_contents_)) {
|
||||
return browser->IsVisible();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsApp() override { return false; }
|
||||
|
||||
private:
|
||||
// The WebContents for the tab over which the dialog will be modal. This may
|
||||
// be different from the WebContents that requested the dialog, such as with
|
||||
// Chrome app <webview>s.
|
||||
raw_ptr<content::WebContents> web_contents_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<JavaScriptTabModalDialogManagerDelegateDesktop>
|
||||
CreateAlloyJavaScriptTabModalDialogManagerDelegateDesktop(
|
||||
content::WebContents* web_contents) {
|
||||
return std::make_unique<AlloyJavaScriptTabModalDialogManagerDelegateDesktop>(
|
||||
web_contents);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// Copyright 2022 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_ALLOY_DIALOGS_ALLOY_JAVASCRIPT_DIALOG_MANAGER_DELEGATE_H_
|
||||
#define CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_JAVASCRIPT_DIALOG_MANAGER_DELEGATE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_desktop.h"
|
||||
|
||||
// Creates a JavaScriptTabModalDialogManagerDelegateDesktop for the Chrome
|
||||
// environment.
|
||||
std::unique_ptr<JavaScriptTabModalDialogManagerDelegateDesktop>
|
||||
CreateAlloyJavaScriptTabModalDialogManagerDelegateDesktop(
|
||||
content::WebContents* web_contents);
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_JAVASCRIPT_DIALOG_MANAGER_DELEGATE_H_
|
@ -0,0 +1,96 @@
|
||||
// Copyright (c) 2019 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/alloy/dialogs/alloy_web_contents_dialog_helper.h"
|
||||
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
|
||||
#include "base/notreached.h"
|
||||
#include "chrome/browser/platform_util.h"
|
||||
#include "components/web_modal/web_contents_modal_dialog_manager.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
AlloyWebContentsDialogHelper::AlloyWebContentsDialogHelper(
|
||||
content::WebContents* web_contents,
|
||||
CefBrowserPlatformDelegate* browser_delegate)
|
||||
: browser_delegate_(browser_delegate), weak_factory_(this) {
|
||||
web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents);
|
||||
web_modal::WebContentsModalDialogManager::FromWebContents(web_contents)
|
||||
->SetDelegate(this);
|
||||
}
|
||||
|
||||
base::RepeatingClosure
|
||||
AlloyWebContentsDialogHelper::GetBoundsChangedCallback() {
|
||||
return base::BindRepeating(&AlloyWebContentsDialogHelper::OnBoundsChanged,
|
||||
weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
bool AlloyWebContentsDialogHelper::IsWebContentsVisible(
|
||||
content::WebContents* web_contents) {
|
||||
if (browser_delegate_->IsWindowless()) {
|
||||
return !browser_delegate_->IsHidden();
|
||||
} else if (auto native_view = web_contents->GetNativeView()) {
|
||||
return platform_util::IsVisible(native_view);
|
||||
}
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
web_modal::WebContentsModalDialogHost*
|
||||
AlloyWebContentsDialogHelper::GetWebContentsModalDialogHost() {
|
||||
return this;
|
||||
}
|
||||
|
||||
gfx::NativeView AlloyWebContentsDialogHelper::GetHostView() const {
|
||||
// Windowless rendering uses GetHostWidget() instead.
|
||||
if (browser_delegate_->IsWindowless()) {
|
||||
return gfx::NativeView();
|
||||
}
|
||||
|
||||
if (auto widget = browser_delegate_->GetWindowWidget()) {
|
||||
return widget->GetNativeView();
|
||||
}
|
||||
NOTREACHED();
|
||||
return gfx::NativeView();
|
||||
}
|
||||
|
||||
gfx::AcceleratedWidget AlloyWebContentsDialogHelper::GetHostWidget() const {
|
||||
#if defined(USE_AURA)
|
||||
// Windowed rendering uses GetHostView() instead.
|
||||
if (!browser_delegate_->IsWindowless()) {
|
||||
return gfx::kNullAcceleratedWidget;
|
||||
}
|
||||
|
||||
if (auto parent_widget = browser_delegate_->GetHostWindowHandle()) {
|
||||
return parent_widget;
|
||||
}
|
||||
#endif // defined(USE_AURA)
|
||||
NOTREACHED();
|
||||
return gfx::kNullAcceleratedWidget;
|
||||
}
|
||||
|
||||
gfx::Point AlloyWebContentsDialogHelper::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
return browser_delegate_->GetDialogPosition(size);
|
||||
}
|
||||
|
||||
gfx::Size AlloyWebContentsDialogHelper::GetMaximumDialogSize() {
|
||||
return browser_delegate_->GetMaximumDialogSize();
|
||||
}
|
||||
|
||||
void AlloyWebContentsDialogHelper::AddObserver(
|
||||
web_modal::ModalDialogHostObserver* observer) {
|
||||
if (observer && !observer_list_.HasObserver(observer))
|
||||
observer_list_.AddObserver(observer);
|
||||
}
|
||||
|
||||
void AlloyWebContentsDialogHelper::RemoveObserver(
|
||||
web_modal::ModalDialogHostObserver* observer) {
|
||||
observer_list_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
void AlloyWebContentsDialogHelper::OnBoundsChanged() {
|
||||
for (auto& observer : observer_list_)
|
||||
observer.OnPositionRequiresUpdate();
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
// 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_WEB_CONTENTS_DIALOG_HELPER_H_
|
||||
#define CEF_LIBCEF_BROWSER_WEB_CONTENTS_DIALOG_HELPER_H_
|
||||
#ifndef CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_WEB_CONTENTS_DIALOG_HELPER_H_
|
||||
#define CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_WEB_CONTENTS_DIALOG_HELPER_H_
|
||||
#pragma once
|
||||
|
||||
#include "base/callback_forward.h"
|
||||
@ -15,11 +15,11 @@
|
||||
|
||||
class CefBrowserPlatformDelegate;
|
||||
|
||||
class CefWebContentsDialogHelper
|
||||
class AlloyWebContentsDialogHelper
|
||||
: public web_modal::WebContentsModalDialogManagerDelegate,
|
||||
public web_modal::WebContentsModalDialogHost {
|
||||
public:
|
||||
CefWebContentsDialogHelper(content::WebContents* web_contents,
|
||||
AlloyWebContentsDialogHelper(content::WebContents* web_contents,
|
||||
CefBrowserPlatformDelegate* browser_delegate);
|
||||
|
||||
base::RepeatingClosure GetBoundsChangedCallback();
|
||||
@ -31,6 +31,7 @@ class CefWebContentsDialogHelper
|
||||
|
||||
// web_modal::WebContentsModalDialogHost methods:
|
||||
gfx::NativeView GetHostView() const override;
|
||||
gfx::AcceleratedWidget GetHostWidget() const override;
|
||||
gfx::Point GetDialogPosition(const gfx::Size& size) override;
|
||||
gfx::Size GetMaximumDialogSize() override;
|
||||
void AddObserver(web_modal::ModalDialogHostObserver* observer) override;
|
||||
@ -45,7 +46,7 @@ class CefWebContentsDialogHelper
|
||||
base::ObserverList<web_modal::ModalDialogHostObserver>::Unchecked
|
||||
observer_list_;
|
||||
|
||||
base::WeakPtrFactory<CefWebContentsDialogHelper> weak_factory_;
|
||||
base::WeakPtrFactory<AlloyWebContentsDialogHelper> weak_factory_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_WEB_CONTENTS_DIALOG_HELPER_H_
|
||||
#endif // CEF_LIBCEF_BROWSER_ALLOY_DIALOGS_ALLOY_WEB_CONTENTS_DIALOG_HELPER_H_
|
@ -16,6 +16,7 @@
|
||||
#include "libcef/common/net/url_util.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "chrome/browser/platform_util.h"
|
||||
#include "chrome/browser/spellchecker/spellcheck_factory.h"
|
||||
#include "chrome/browser/spellchecker/spellcheck_service.h"
|
||||
#include "components/favicon/core/favicon_url.h"
|
||||
@ -138,6 +139,39 @@ CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetBrowserForGlobalId(
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserHostBase>
|
||||
CefBrowserHostBase::GetBrowserForTopLevelNativeWindow(
|
||||
gfx::NativeWindow owning_window) {
|
||||
DCHECK(owning_window);
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
for (const auto& browser_info :
|
||||
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
|
||||
if (auto browser = browser_info->browser()) {
|
||||
if (browser->GetTopLevelNativeWindow() == owning_window)
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
CefRefPtr<CefBrowserHostBase> CefBrowserHostBase::GetLikelyFocusedBrowser() {
|
||||
CEF_REQUIRE_UIT();
|
||||
|
||||
for (const auto& browser_info :
|
||||
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
|
||||
if (auto browser = browser_info->browser()) {
|
||||
if (browser->IsFocused())
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefBrowserHostBase::CefBrowserHostBase(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
@ -975,6 +1009,18 @@ bool CefBrowserHostBase::IsFocused() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::IsVisible() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
// Windowless browsers always return nullptr from GetNativeView().
|
||||
if (!IsWindowless()) {
|
||||
auto web_contents = GetWebContents();
|
||||
if (web_contents) {
|
||||
return platform_util::IsVisible(web_contents->GetNativeView());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CefBrowserHostBase::EnsureDevToolsManager() {
|
||||
CEF_REQUIRE_UIT();
|
||||
if (!contents_delegate_->web_contents())
|
||||
|
@ -128,6 +128,14 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
// Returns the browser associated with the specified global ID.
|
||||
static CefRefPtr<CefBrowserHostBase> GetBrowserForGlobalId(
|
||||
const content::GlobalRenderFrameHostId& global_id);
|
||||
// Returns the browser associated with the specified top-level window.
|
||||
static CefRefPtr<CefBrowserHostBase> GetBrowserForTopLevelNativeWindow(
|
||||
gfx::NativeWindow owning_window);
|
||||
|
||||
// Returns the browser most likely to be focused. This may be somewhat iffy
|
||||
// with windowless browsers as there is no guarantee that the client has only
|
||||
// one browser focused at a time.
|
||||
static CefRefPtr<CefBrowserHostBase> GetLikelyFocusedBrowser();
|
||||
|
||||
CefBrowserHostBase(
|
||||
const CefBrowserSettings& settings,
|
||||
@ -146,6 +154,10 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
// destroyed.
|
||||
virtual void WindowDestroyed() = 0;
|
||||
|
||||
// Returns true if the browser is in the process of being destroyed. Called on
|
||||
// the UI thread only.
|
||||
virtual bool WillBeDestroyed() const = 0;
|
||||
|
||||
// Called on the UI thread after the associated WebContents is destroyed.
|
||||
// Also called from CefBrowserInfoManager::DestroyAllBrowsers if the browser
|
||||
// was not properly shut down.
|
||||
@ -312,6 +324,9 @@ class CefBrowserHostBase : public CefBrowserHost,
|
||||
// on the client to properly configure focus state.
|
||||
bool IsFocused() const;
|
||||
|
||||
// Returns true if this browser is currently visible.
|
||||
virtual bool IsVisible() const;
|
||||
|
||||
protected:
|
||||
bool EnsureDevToolsManager();
|
||||
void InitializeDevToolsRegistrationOnUIThread(
|
||||
|
@ -131,6 +131,12 @@ CefRefPtr<CefBrowserView> CefBrowserPlatformDelegate::GetBrowserView() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
web_modal::WebContentsModalDialogHost*
|
||||
CefBrowserPlatformDelegate::GetWebContentsModalDialogHost() const {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::PopupWebContentsCreated(
|
||||
const CefBrowserSettings& settings,
|
||||
CefRefPtr<CefClient> client,
|
||||
@ -226,7 +232,6 @@ CefEventHandle CefBrowserPlatformDelegate::GetEventHandle(
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegate::CreateJavaScriptDialogRunner() {
|
||||
NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -253,6 +258,11 @@ void CefBrowserPlatformDelegate::WasHidden(bool hidden) {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegate::IsHidden() const {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::NotifyScreenInfoChanged() {
|
||||
NOTREACHED();
|
||||
}
|
||||
@ -351,13 +361,18 @@ void CefBrowserPlatformDelegate::AccessibilityLocationChangesReceived(
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegate::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
NOTREACHED();
|
||||
return gfx::Point();
|
||||
const gfx::Size& max_size = GetMaximumDialogSize();
|
||||
return gfx::Point((max_size.width() - size.width()) / 2,
|
||||
(max_size.height() - size.height()) / 2);
|
||||
}
|
||||
|
||||
gfx::Size CefBrowserPlatformDelegate::GetMaximumDialogSize() {
|
||||
NOTREACHED();
|
||||
if (!web_contents_)
|
||||
return gfx::Size();
|
||||
|
||||
// The dialog should try to fit within the overlay for the web contents.
|
||||
// Note that, for things like print preview, this is just a suggested maximum.
|
||||
return web_contents_->GetContainerBounds().size();
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegate::SetAutoResizeEnabled(bool enabled,
|
||||
|
@ -61,6 +61,10 @@ namespace views {
|
||||
class Widget;
|
||||
}
|
||||
|
||||
namespace web_modal {
|
||||
class WebContentsModalDialogHost;
|
||||
}
|
||||
|
||||
struct CefBrowserCreateParams;
|
||||
class CefBrowserHostBase;
|
||||
class CefJavaScriptDialogRunner;
|
||||
@ -178,6 +182,10 @@ class CefBrowserPlatformDelegate {
|
||||
// based browsers.
|
||||
virtual CefRefPtr<CefBrowserView> GetBrowserView() const;
|
||||
|
||||
// Returns the WebContentsModalDialogHost associated with this browser.
|
||||
virtual web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
|
||||
const;
|
||||
|
||||
// Called after the WebContents have been created for a new popup browser
|
||||
// parented to this browser but before the AlloyBrowserHostImpl is created for
|
||||
// the popup. |is_devtools| will be true if the popup will host DevTools. This
|
||||
@ -289,6 +297,10 @@ class CefBrowserPlatformDelegate {
|
||||
// Notify the browser that it was hidden. Only used with windowless rendering.
|
||||
virtual void WasHidden(bool hidden);
|
||||
|
||||
// Returns true if the browser is currently hidden. Only used with windowless
|
||||
// rendering.
|
||||
virtual bool IsHidden() const;
|
||||
|
||||
// Notify the browser that screen information has changed. Only used with
|
||||
// windowless rendering.
|
||||
virtual void NotifyScreenInfoChanged();
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "chrome/browser/ui/browser.h"
|
||||
#include "chrome/browser/ui/browser_window.h"
|
||||
#include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/display/screen.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
@ -47,6 +48,16 @@ CefWindowHandle CefBrowserPlatformDelegateChrome::GetHostWindowHandle() const {
|
||||
return view_util::GetWindowHandle(GetNativeWindow());
|
||||
}
|
||||
|
||||
web_modal::WebContentsModalDialogHost*
|
||||
CefBrowserPlatformDelegateChrome::GetWebContentsModalDialogHost() const {
|
||||
if (chrome_browser_) {
|
||||
ChromeWebModalDialogManagerDelegate* manager = chrome_browser_;
|
||||
return manager->GetWebContentsModalDialogHost();
|
||||
}
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SkColor CefBrowserPlatformDelegateChrome::GetBackgroundColor() const {
|
||||
return native_delegate_->GetBackgroundColor();
|
||||
}
|
||||
@ -124,5 +135,6 @@ void CefBrowserPlatformDelegateChrome::set_chrome_browser(Browser* browser) {
|
||||
gfx::NativeWindow CefBrowserPlatformDelegateChrome::GetNativeWindow() const {
|
||||
if (chrome_browser_ && chrome_browser_->window())
|
||||
return chrome_browser_->window()->GetNativeWindow();
|
||||
NOTREACHED();
|
||||
return gfx::NativeWindow();
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ class CefBrowserPlatformDelegateChrome
|
||||
void BrowserCreated(CefBrowserHostBase* browser) override;
|
||||
void BrowserDestroyed(CefBrowserHostBase* browser) override;
|
||||
CefWindowHandle GetHostWindowHandle() const override;
|
||||
web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost()
|
||||
const override;
|
||||
SkColor GetBackgroundColor() const override;
|
||||
void SendKeyEvent(const CefKeyEvent& event) override;
|
||||
void SendMouseClickEvent(const CefMouseEvent& event,
|
||||
|
@ -538,6 +538,12 @@ void ChromeBrowserHostImpl::WindowDestroyed() {
|
||||
platform_delegate_->CloseHostWindow();
|
||||
}
|
||||
|
||||
bool ChromeBrowserHostImpl::WillBeDestroyed() const {
|
||||
CEF_REQUIRE_UIT();
|
||||
// TODO(chrome): Modify this to support DoClose(), see issue #3294.
|
||||
return !!browser_;
|
||||
}
|
||||
|
||||
void ChromeBrowserHostImpl::DestroyBrowser() {
|
||||
CEF_REQUIRE_UIT();
|
||||
browser_ = nullptr;
|
||||
|
@ -150,6 +150,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
||||
|
||||
// CefBrowserHostBase methods:
|
||||
void WindowDestroyed() override;
|
||||
bool WillBeDestroyed() const override;
|
||||
void DestroyBrowser() override;
|
||||
|
||||
void DoCloseBrowser(bool force_close);
|
||||
|
@ -103,11 +103,6 @@ CefEventHandle CefBrowserPlatformDelegateBackground::GetEventHandle(
|
||||
return native_delegate_->GetEventHandle(event);
|
||||
}
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegateBackground::CreateJavaScriptDialogRunner() {
|
||||
return native_delegate_->CreateJavaScriptDialogRunner();
|
||||
}
|
||||
|
||||
std::unique_ptr<CefMenuRunner>
|
||||
CefBrowserPlatformDelegateBackground::CreateMenuRunner() {
|
||||
// No default menu implementation for background browsers.
|
||||
|
@ -41,8 +41,6 @@ class CefBrowserPlatformDelegateBackground
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
CefEventHandle GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const override;
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
|
||||
override;
|
||||
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
|
||||
// CefBrowserPlatformDelegateNative::WindowlessHandler methods:
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "libcef/browser/file_dialog_runner.h"
|
||||
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
#include "libcef/browser/browser_info_manager.h"
|
||||
#include "libcef/browser/extensions/browser_extensions_util.h"
|
||||
|
||||
#include "base/memory/singleton.h"
|
||||
@ -50,32 +49,6 @@ class CefSelectFileDialogFactory final : public ui::SelectFileDialogFactory {
|
||||
CefSelectFileDialogFactory() { ui::SelectFileDialog::SetFactory(this); }
|
||||
};
|
||||
|
||||
CefRefPtr<CefBrowserHostBase> GetBrowserForTopLevelNativeWindow(
|
||||
gfx::NativeWindow owning_window) {
|
||||
DCHECK(owning_window);
|
||||
for (const auto& browser_info :
|
||||
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
|
||||
if (auto browser = browser_info->browser()) {
|
||||
if (browser->GetTopLevelNativeWindow() == owning_window)
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserHostBase> GetLikelyFocusedBrowser() {
|
||||
for (const auto& browser_info :
|
||||
CefBrowserInfoManager::GetInstance()->GetBrowserInfoList()) {
|
||||
if (auto browser = browser_info->browser()) {
|
||||
if (browser->IsFocused())
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Delegates the running of the dialog to CefFileDialogManager.
|
||||
class CefSelectFileDialog final : public ui::SelectFileDialog {
|
||||
public:
|
||||
@ -118,7 +91,8 @@ class CefSelectFileDialog final : public ui::SelectFileDialog {
|
||||
// This should be reliable with windowed browsers. However, |owning_window|
|
||||
// will always be nullptr with windowless browsers.
|
||||
if (!browser_ && owning_window) {
|
||||
browser_ = GetBrowserForTopLevelNativeWindow(owning_window);
|
||||
browser_ =
|
||||
CefBrowserHostBase::GetBrowserForTopLevelNativeWindow(owning_window);
|
||||
if (!browser_) {
|
||||
LOG(WARNING) << "No browser associated with top-level native window";
|
||||
}
|
||||
@ -128,7 +102,7 @@ class CefSelectFileDialog final : public ui::SelectFileDialog {
|
||||
// windowless browsers as there is no guarantee that the client has only
|
||||
// one browser focused at a time.
|
||||
if (!browser_) {
|
||||
browser_ = GetLikelyFocusedBrowser();
|
||||
browser_ = CefBrowserHostBase::GetLikelyFocusedBrowser();
|
||||
if (!browser_) {
|
||||
LOG(WARNING) << "No likely focused browser";
|
||||
}
|
||||
|
@ -7,13 +7,13 @@
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
|
||||
#include "libcef/browser/browser_host_base.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "components/url_formatter/elide_url.h"
|
||||
#include "components/javascript_dialogs/tab_modal_dialog_manager.h"
|
||||
|
||||
namespace {
|
||||
|
||||
@ -60,21 +60,26 @@ class CefJSDialogCallbackImpl : public CefJSDialogCallback {
|
||||
IMPLEMENT_REFCOUNTING(CefJSDialogCallbackImpl);
|
||||
};
|
||||
|
||||
javascript_dialogs::TabModalDialogManager* GetTabModalDialogManager(
|
||||
content::WebContents* web_contents) {
|
||||
return javascript_dialogs::TabModalDialogManager::FromWebContents(
|
||||
web_contents);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefJavaScriptDialogManager::CefJavaScriptDialogManager(
|
||||
AlloyBrowserHostImpl* browser,
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> runner)
|
||||
: browser_(browser),
|
||||
runner_(std::move(runner)),
|
||||
dialog_running_(false),
|
||||
weak_ptr_factory_(this) {}
|
||||
CefBrowserHostBase* browser)
|
||||
: browser_(browser), weak_ptr_factory_(this) {}
|
||||
|
||||
CefJavaScriptDialogManager::~CefJavaScriptDialogManager() {}
|
||||
|
||||
void CefJavaScriptDialogManager::Destroy() {
|
||||
if (runner_.get()) {
|
||||
runner_.reset(nullptr);
|
||||
if (handler_) {
|
||||
CancelDialogs(nullptr, false);
|
||||
}
|
||||
if (runner_) {
|
||||
runner_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,13 +91,19 @@ void CefJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback,
|
||||
bool* did_suppress_message) {
|
||||
*did_suppress_message = false;
|
||||
|
||||
const GURL& origin_url = render_frame_host->GetLastCommittedURL();
|
||||
|
||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
|
||||
if (handler.get()) {
|
||||
*did_suppress_message = false;
|
||||
// Always call DialogClosed().
|
||||
callback =
|
||||
base::BindOnce(&CefJavaScriptDialogManager::DialogClosed,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
|
||||
|
||||
if (auto client = browser_->GetClient()) {
|
||||
if (auto handler = client->GetJSDialogHandler()) {
|
||||
// If the dialog is handled this will be cleared in DialogClosed().
|
||||
handler_ = handler;
|
||||
|
||||
CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
|
||||
new CefJSDialogCallbackImpl(std::move(callback)));
|
||||
@ -110,32 +121,40 @@ void CefJavaScriptDialogManager::RunJavaScriptDialog(
|
||||
|
||||
// |callback| may be null if the user executed it despite returning false.
|
||||
callback = callbackPtr->Disconnect();
|
||||
if (callback.is_null() || *did_suppress_message)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*did_suppress_message = false;
|
||||
|
||||
if (!runner_.get() || dialog_running_) {
|
||||
// Suppress the dialog if there is no platform runner or if the dialog is
|
||||
// currently running.
|
||||
if (!runner_.get())
|
||||
LOG(WARNING) << "No javascript dialog runner available for this platform";
|
||||
*did_suppress_message = true;
|
||||
if (callback.is_null()) {
|
||||
LOG(WARNING)
|
||||
<< "OnJSDialog should return true when executing the callback";
|
||||
return;
|
||||
}
|
||||
|
||||
dialog_running_ = true;
|
||||
if (*did_suppress_message) {
|
||||
// Call OnResetDialogState but don't execute |callback|.
|
||||
CancelDialogs(web_contents, /*reset_state=*/true);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::u16string& display_url =
|
||||
url_formatter::FormatUrlForSecurityDisplay(origin_url);
|
||||
handler_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DCHECK(!callback.is_null());
|
||||
runner_->Run(
|
||||
browser_, message_type, display_url, message_text, default_prompt_text,
|
||||
base::BindOnce(&CefJavaScriptDialogManager::DialogClosed,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
|
||||
DCHECK(!handler_);
|
||||
|
||||
if (InitializeRunner()) {
|
||||
runner_->Run(browser_, message_type, origin_url, message_text,
|
||||
default_prompt_text, std::move(callback));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanUseChromeDialogs()) {
|
||||
// Dismiss the dialog.
|
||||
std::move(callback).Run(false, std::u16string());
|
||||
return;
|
||||
}
|
||||
|
||||
auto manager = GetTabModalDialogManager(web_contents);
|
||||
manager->RunJavaScriptDialog(web_contents, render_frame_host, message_type,
|
||||
message_text, default_prompt_text,
|
||||
std::move(callback), did_suppress_message);
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||
@ -143,8 +162,7 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
bool is_reload,
|
||||
DialogClosedCallback callback) {
|
||||
if (browser_->destruction_state() >=
|
||||
AlloyBrowserHostImpl::DESTRUCTION_STATE_ACCEPTED) {
|
||||
if (browser_->WillBeDestroyed()) {
|
||||
// Currently destroying the browser. Accept the unload without showing
|
||||
// the prompt.
|
||||
std::move(callback).Run(true, std::u16string());
|
||||
@ -153,80 +171,138 @@ void CefJavaScriptDialogManager::RunBeforeUnloadDialog(
|
||||
|
||||
const std::u16string& message_text = u"Is it OK to leave/reload this page?";
|
||||
|
||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
|
||||
if (handler.get()) {
|
||||
// Always call DialogClosed().
|
||||
callback =
|
||||
base::BindOnce(&CefJavaScriptDialogManager::DialogClosed,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(callback));
|
||||
|
||||
if (auto client = browser_->GetClient()) {
|
||||
if (auto handler = client->GetJSDialogHandler()) {
|
||||
// If the dialog is handled this will be cleared in DialogClosed().
|
||||
handler_ = handler;
|
||||
|
||||
CefRefPtr<CefJSDialogCallbackImpl> callbackPtr(
|
||||
new CefJSDialogCallbackImpl(std::move(callback)));
|
||||
|
||||
// Execute the user callback.
|
||||
bool handled = handler->OnBeforeUnloadDialog(
|
||||
browser_, message_text, is_reload, callbackPtr.get());
|
||||
if (handled)
|
||||
if (handled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// |callback| may be null if the user executed it despite returning false.
|
||||
callback = callbackPtr->Disconnect();
|
||||
if (callback.is_null())
|
||||
if (callback.is_null()) {
|
||||
LOG(WARNING) << "OnBeforeUnloadDialog should return true when "
|
||||
"executing the callback";
|
||||
return;
|
||||
}
|
||||
|
||||
handler_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!runner_.get() || dialog_running_) {
|
||||
if (!runner_.get())
|
||||
LOG(WARNING) << "No javascript dialog runner available for this platform";
|
||||
// Suppress the dialog if there is no platform runner or if the dialog is
|
||||
// currently running.
|
||||
DCHECK(!handler_);
|
||||
|
||||
if (InitializeRunner()) {
|
||||
runner_->Run(browser_, content::JAVASCRIPT_DIALOG_TYPE_CONFIRM,
|
||||
/*origin_url=*/GURL(), message_text,
|
||||
/*default_prompt_text=*/std::u16string(), std::move(callback));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanUseChromeDialogs()) {
|
||||
// Accept the unload without showing the prompt.
|
||||
std::move(callback).Run(true, std::u16string());
|
||||
return;
|
||||
}
|
||||
|
||||
dialog_running_ = true;
|
||||
auto manager = GetTabModalDialogManager(web_contents);
|
||||
manager->RunBeforeUnloadDialog(web_contents, render_frame_host, is_reload,
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
DCHECK(!callback.is_null());
|
||||
runner_->Run(
|
||||
browser_, content::JAVASCRIPT_DIALOG_TYPE_CONFIRM,
|
||||
std::u16string(), // display_url
|
||||
message_text,
|
||||
std::u16string(), // default_prompt_text
|
||||
base::BindOnce(&CefJavaScriptDialogManager::DialogClosed,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
|
||||
bool CefJavaScriptDialogManager::HandleJavaScriptDialog(
|
||||
content::WebContents* web_contents,
|
||||
bool accept,
|
||||
const std::u16string* prompt_override) {
|
||||
if (handler_) {
|
||||
DialogClosed(base::NullCallback(), accept,
|
||||
prompt_override ? *prompt_override : std::u16string());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (runner_) {
|
||||
runner_->Handle(accept, prompt_override);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CanUseChromeDialogs())
|
||||
return true;
|
||||
|
||||
auto manager = GetTabModalDialogManager(web_contents);
|
||||
return manager->HandleJavaScriptDialog(web_contents, accept, prompt_override);
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogManager::CancelDialogs(
|
||||
content::WebContents* web_contents,
|
||||
bool reset_state) {
|
||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
|
||||
if (handler.get()) {
|
||||
// Execute the user callback.
|
||||
handler->OnResetDialogState(browser_);
|
||||
if (handler_) {
|
||||
if (reset_state) {
|
||||
handler_->OnResetDialogState(browser_);
|
||||
}
|
||||
handler_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (runner_.get() && dialog_running_) {
|
||||
if (runner_) {
|
||||
runner_->Cancel();
|
||||
dialog_running_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Null when called from DialogClosed() or Destroy().
|
||||
if (!web_contents)
|
||||
return;
|
||||
|
||||
if (!CanUseChromeDialogs())
|
||||
return;
|
||||
|
||||
auto manager = GetTabModalDialogManager(web_contents);
|
||||
manager->CancelDialogs(web_contents, reset_state);
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogManager::DialogClosed(
|
||||
DialogClosedCallback callback,
|
||||
bool success,
|
||||
const std::u16string& user_input) {
|
||||
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||
if (client.get()) {
|
||||
CefRefPtr<CefJSDialogHandler> handler = client->GetJSDialogHandler();
|
||||
if (handler.get())
|
||||
handler->OnDialogClosed(browser_);
|
||||
if (handler_) {
|
||||
handler_->OnDialogClosed(browser_);
|
||||
// Call OnResetDialogState.
|
||||
CancelDialogs(/*web_contents=*/nullptr, /*reset_state=*/true);
|
||||
}
|
||||
|
||||
DCHECK(runner_.get());
|
||||
DCHECK(dialog_running_);
|
||||
|
||||
dialog_running_ = false;
|
||||
|
||||
// Null when called from HandleJavaScriptDialog().
|
||||
if (!callback.is_null()) {
|
||||
std::move(callback).Run(success, user_input);
|
||||
}
|
||||
}
|
||||
|
||||
bool CefJavaScriptDialogManager::InitializeRunner() {
|
||||
if (!runner_initialized_) {
|
||||
runner_ = browser_->platform_delegate()->CreateJavaScriptDialogRunner();
|
||||
runner_initialized_ = true;
|
||||
}
|
||||
return !!runner_.get();
|
||||
}
|
||||
|
||||
bool CefJavaScriptDialogManager::CanUseChromeDialogs() const {
|
||||
if (browser_->IsWindowless() &&
|
||||
browser_->GetWindowHandle() == kNullWindowHandle) {
|
||||
LOG(ERROR) << "Default dialog implementation requires a parent window "
|
||||
"handle; canceling the JS dialog";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
@ -7,20 +7,21 @@
|
||||
#define CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_MANAGER_H_
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "include/cef_jsdialog_handler.h"
|
||||
#include "libcef/browser/javascript_dialog_runner.h"
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "content/public/browser/javascript_dialog_manager.h"
|
||||
|
||||
class AlloyBrowserHostImpl;
|
||||
class CefBrowserHostBase;
|
||||
|
||||
class CefJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
public:
|
||||
// |runner| may be NULL if the platform doesn't implement dialogs.
|
||||
CefJavaScriptDialogManager(AlloyBrowserHostImpl* browser,
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> runner);
|
||||
explicit CefJavaScriptDialogManager(CefBrowserHostBase* browser);
|
||||
|
||||
CefJavaScriptDialogManager(const CefJavaScriptDialogManager&) = delete;
|
||||
CefJavaScriptDialogManager& operator=(const CefJavaScriptDialogManager&) =
|
||||
@ -43,6 +44,9 @@ class CefJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
content::RenderFrameHost* render_frame_host,
|
||||
bool is_reload,
|
||||
DialogClosedCallback callback) override;
|
||||
bool HandleJavaScriptDialog(content::WebContents* web_contents,
|
||||
bool accept,
|
||||
const std::u16string* prompt_override) override;
|
||||
void CancelDialogs(content::WebContents* web_contents,
|
||||
bool reset_state) override;
|
||||
|
||||
@ -52,13 +56,17 @@ class CefJavaScriptDialogManager : public content::JavaScriptDialogManager {
|
||||
bool success,
|
||||
const std::u16string& user_input);
|
||||
|
||||
// AlloyBrowserHostImpl pointer is guaranteed to outlive this object.
|
||||
AlloyBrowserHostImpl* browser_;
|
||||
bool InitializeRunner();
|
||||
|
||||
bool CanUseChromeDialogs() const;
|
||||
|
||||
// CefBrowserHostBase pointer is guaranteed to outlive this object.
|
||||
CefBrowserHostBase* const browser_;
|
||||
|
||||
CefRefPtr<CefJSDialogHandler> handler_;
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> runner_;
|
||||
|
||||
// True if a dialog is currently running.
|
||||
bool dialog_running_;
|
||||
bool runner_initialized_ = false;
|
||||
|
||||
// Must be the last member.
|
||||
base::WeakPtrFactory<CefJavaScriptDialogManager> weak_ptr_factory_;
|
||||
|
@ -7,10 +7,10 @@
|
||||
#define CEF_LIBCEF_BROWSER_JAVASCRIPT_DIALOG_RUNNER_H_
|
||||
#pragma once
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "content/public/browser/javascript_dialog_manager.h"
|
||||
#include "content/public/common/javascript_dialog_type.h"
|
||||
|
||||
class AlloyBrowserHostImpl;
|
||||
class CefBrowserHostBase;
|
||||
|
||||
class CefJavaScriptDialogRunner {
|
||||
public:
|
||||
@ -19,17 +19,19 @@ class CefJavaScriptDialogRunner {
|
||||
delete;
|
||||
|
||||
using DialogClosedCallback =
|
||||
base::OnceCallback<void(bool /* success */,
|
||||
const std::u16string& /* user_input */)>;
|
||||
content::JavaScriptDialogManager::DialogClosedCallback;
|
||||
|
||||
// Run the dialog. Execute |callback| on completion.
|
||||
virtual void Run(AlloyBrowserHostImpl* browser,
|
||||
virtual void Run(CefBrowserHostBase* browser,
|
||||
content::JavaScriptDialogType message_type,
|
||||
const std::u16string& display_url,
|
||||
const GURL& origin_url,
|
||||
const std::u16string& message_text,
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback) = 0;
|
||||
|
||||
// Dismiss the dialog with the specified results.
|
||||
virtual void Handle(bool accept, const std::u16string* prompt_override) = 0;
|
||||
|
||||
// Cancel a dialog mid-flight.
|
||||
virtual void Cancel() = 0;
|
||||
|
||||
|
@ -233,17 +233,6 @@ CefEventHandle CefBrowserPlatformDelegateNativeLinux::GetEventHandle(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegateNativeLinux::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
const gfx::Size& max_size = GetMaximumDialogSize();
|
||||
return gfx::Point((max_size.width() - size.width()) / 2,
|
||||
(max_size.height() - size.height()) / 2);
|
||||
}
|
||||
|
||||
gfx::Size CefBrowserPlatformDelegateNativeLinux::GetMaximumDialogSize() {
|
||||
return GetWindowWidget()->GetWindowBoundsInScreen().size();
|
||||
}
|
||||
|
||||
ui::KeyEvent CefBrowserPlatformDelegateNativeLinux::TranslateUiKeyEvent(
|
||||
const CefKeyEvent& key_event) const {
|
||||
int flags = TranslateUiEventModifiers(key_event.modifiers);
|
||||
|
@ -34,8 +34,6 @@ class CefBrowserPlatformDelegateNativeLinux
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
CefEventHandle GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const override;
|
||||
gfx::Point GetDialogPosition(const gfx::Size& size) override;
|
||||
gfx::Size GetMaximumDialogSize() override;
|
||||
|
||||
// CefBrowserPlatformDelegateNativeAura methods:
|
||||
ui::KeyEvent TranslateUiKeyEvent(const CefKeyEvent& key_event) const override;
|
||||
|
@ -44,8 +44,6 @@ class CefBrowserPlatformDelegateNativeMac
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
|
||||
override;
|
||||
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
gfx::Point GetDialogPosition(const gfx::Size& size) override;
|
||||
gfx::Size GetMaximumDialogSize() override;
|
||||
|
||||
// CefBrowserPlatformDelegateNative methods:
|
||||
content::NativeWebKeyboardEvent TranslateWebKeyEvent(
|
||||
|
@ -374,22 +374,6 @@ CefBrowserPlatformDelegateNativeMac::CreateMenuRunner() {
|
||||
return base::WrapUnique(new CefMenuRunnerMac);
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegateNativeMac::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
// Dialogs are always re-positioned by the constrained window sheet controller
|
||||
// so nothing interesting to return yet.
|
||||
return gfx::Point();
|
||||
}
|
||||
|
||||
gfx::Size CefBrowserPlatformDelegateNativeMac::GetMaximumDialogSize() {
|
||||
if (!web_contents_)
|
||||
return gfx::Size();
|
||||
|
||||
// The dialog should try to fit within the overlay for the web contents.
|
||||
// Note that, for things like print preview, this is just a suggested maximum.
|
||||
return web_contents_->GetContainerBounds().size();
|
||||
}
|
||||
|
||||
content::NativeWebKeyboardEvent
|
||||
CefBrowserPlatformDelegateNativeMac::TranslateWebKeyEvent(
|
||||
const CefKeyEvent& key_event) const {
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
|
||||
#include "libcef/browser/context.h"
|
||||
#include "libcef/browser/native/javascript_dialog_runner_win.h"
|
||||
#include "libcef/browser/native/window_delegate_view.h"
|
||||
#include "libcef/browser/thread_util.h"
|
||||
|
||||
@ -425,22 +424,6 @@ CefEventHandle CefBrowserPlatformDelegateNativeWin::GetEventHandle(
|
||||
const_cast<CHROME_MSG*>(&event.os_event->native_event()));
|
||||
}
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegateNativeWin::CreateJavaScriptDialogRunner() {
|
||||
return base::WrapUnique(new CefJavaScriptDialogRunnerWin);
|
||||
}
|
||||
|
||||
gfx::Point CefBrowserPlatformDelegateNativeWin::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
const gfx::Size& max_size = GetMaximumDialogSize();
|
||||
return gfx::Point((max_size.width() - size.width()) / 2,
|
||||
(max_size.height() - size.height()) / 2);
|
||||
}
|
||||
|
||||
gfx::Size CefBrowserPlatformDelegateNativeWin::GetMaximumDialogSize() {
|
||||
return GetWindowWidget()->GetWindowBoundsInScreen().size();
|
||||
}
|
||||
|
||||
ui::KeyEvent CefBrowserPlatformDelegateNativeWin::TranslateUiKeyEvent(
|
||||
const CefKeyEvent& key_event) const {
|
||||
int flags = TranslateUiEventModifiers(key_event.modifiers);
|
||||
|
@ -33,10 +33,6 @@ class CefBrowserPlatformDelegateNativeWin
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
CefEventHandle GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const override;
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
|
||||
override;
|
||||
gfx::Point GetDialogPosition(const gfx::Size& size) override;
|
||||
gfx::Size GetMaximumDialogSize() override;
|
||||
|
||||
// CefBrowserPlatformDelegateNativeAura methods:
|
||||
ui::KeyEvent TranslateUiKeyEvent(const CefKeyEvent& key_event) const override;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "libcef/browser/javascript_dialog_runner.h"
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
|
||||
@ -24,12 +25,13 @@ class CefJavaScriptDialogRunnerMac : public CefJavaScriptDialogRunner {
|
||||
~CefJavaScriptDialogRunnerMac() override;
|
||||
|
||||
// CefJavaScriptDialogRunner methods:
|
||||
void Run(AlloyBrowserHostImpl* browser,
|
||||
void Run(CefBrowserHostBase* browser,
|
||||
content::JavaScriptDialogType message_type,
|
||||
const std::u16string& display_url,
|
||||
const GURL& origin_url,
|
||||
const std::u16string& message_text,
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback) override;
|
||||
void Handle(bool accept, const std::u16string* prompt_override) override;
|
||||
void Cancel() override;
|
||||
|
||||
// Callback from CefJavaScriptDialogHelper when the dialog is closed.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "components/url_formatter/elide_url.h"
|
||||
|
||||
// Helper object that receives the notification that the dialog/sheet is
|
||||
// going away. Is responsible for cleaning itself up.
|
||||
@ -87,9 +88,9 @@ CefJavaScriptDialogRunnerMac::~CefJavaScriptDialogRunnerMac() {
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerMac::Run(
|
||||
AlloyBrowserHostImpl* browser,
|
||||
CefBrowserHostBase* browser,
|
||||
content::JavaScriptDialogType message_type,
|
||||
const std::u16string& display_url,
|
||||
const GURL& origin_url,
|
||||
const std::u16string& message_text,
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback) {
|
||||
@ -126,6 +127,9 @@ void CefJavaScriptDialogRunnerMac::Run(
|
||||
label = u"JavaScript Confirm";
|
||||
break;
|
||||
}
|
||||
|
||||
const std::u16string& display_url =
|
||||
url_formatter::FormatUrlForSecurityDisplay(origin_url);
|
||||
if (!display_url.empty())
|
||||
label += u" - " + display_url;
|
||||
|
||||
@ -156,6 +160,14 @@ void CefJavaScriptDialogRunnerMac::Run(
|
||||
[[alert window] makeFirstResponder:[alert accessoryView]];
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerMac::Handle(
|
||||
bool accept,
|
||||
const std::u16string* prompt_override) {
|
||||
if (helper_.get()) {
|
||||
DialogClosed(accept, prompt_override ? *prompt_override : std::u16string());
|
||||
}
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerMac::Cancel() {
|
||||
if (helper_.get()) {
|
||||
[helper_ cancel];
|
||||
|
@ -1,240 +0,0 @@
|
||||
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2012 The Chromium 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/native/javascript_dialog_runner_win.h"
|
||||
|
||||
#include "libcef/browser/alloy/alloy_browser_host_impl.h"
|
||||
#include "libcef_dll/resource.h"
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/path_service.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
|
||||
class CefJavaScriptDialogRunnerWin;
|
||||
|
||||
HHOOK CefJavaScriptDialogRunnerWin::msg_hook_ = NULL;
|
||||
int CefJavaScriptDialogRunnerWin::msg_hook_user_count_ = 0;
|
||||
|
||||
INT_PTR CALLBACK CefJavaScriptDialogRunnerWin::DialogProc(HWND dialog,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
switch (message) {
|
||||
case WM_INITDIALOG: {
|
||||
SetWindowLongPtr(dialog, DWLP_USER, static_cast<LONG_PTR>(lparam));
|
||||
CefJavaScriptDialogRunnerWin* owner =
|
||||
reinterpret_cast<CefJavaScriptDialogRunnerWin*>(lparam);
|
||||
owner->dialog_win_ = dialog;
|
||||
SetDlgItemText(dialog, IDC_DIALOGTEXT, owner->message_text_.c_str());
|
||||
if (owner->message_type_ == content::JAVASCRIPT_DIALOG_TYPE_PROMPT)
|
||||
SetDlgItemText(dialog, IDC_PROMPTEDIT,
|
||||
owner->default_prompt_text_.c_str());
|
||||
break;
|
||||
}
|
||||
case WM_CLOSE: {
|
||||
CefJavaScriptDialogRunnerWin* owner =
|
||||
reinterpret_cast<CefJavaScriptDialogRunnerWin*>(
|
||||
GetWindowLongPtr(dialog, DWLP_USER));
|
||||
if (owner) {
|
||||
owner->CloseDialog(false, std::wstring());
|
||||
|
||||
// No need for the system to call DestroyWindow() because it will be
|
||||
// called by the Cancel() method.
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND: {
|
||||
CefJavaScriptDialogRunnerWin* owner =
|
||||
reinterpret_cast<CefJavaScriptDialogRunnerWin*>(
|
||||
GetWindowLongPtr(dialog, DWLP_USER));
|
||||
std::wstring user_input;
|
||||
bool finish = false;
|
||||
bool result = false;
|
||||
switch (LOWORD(wparam)) {
|
||||
case IDOK:
|
||||
finish = true;
|
||||
result = true;
|
||||
if (owner->message_type_ == content::JAVASCRIPT_DIALOG_TYPE_PROMPT) {
|
||||
size_t length =
|
||||
GetWindowTextLength(GetDlgItem(dialog, IDC_PROMPTEDIT)) + 1;
|
||||
if (length > 1) {
|
||||
user_input.reserve(length);
|
||||
user_input.resize(length - 1);
|
||||
GetDlgItemText(dialog, IDC_PROMPTEDIT, &user_input[0], length);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDCANCEL:
|
||||
finish = true;
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
if (finish) {
|
||||
owner->CloseDialog(result, user_input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CefJavaScriptDialogRunnerWin::CefJavaScriptDialogRunnerWin()
|
||||
: dialog_win_(NULL), parent_win_(NULL), hook_installed_(false) {}
|
||||
|
||||
CefJavaScriptDialogRunnerWin::~CefJavaScriptDialogRunnerWin() {
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerWin::Run(
|
||||
AlloyBrowserHostImpl* browser,
|
||||
content::JavaScriptDialogType message_type,
|
||||
const std::u16string& display_url,
|
||||
const std::u16string& message_text,
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback) {
|
||||
DCHECK(!dialog_win_);
|
||||
|
||||
message_type_ = message_type;
|
||||
message_text_ = base::UTF16ToWide(message_text);
|
||||
default_prompt_text_ = base::UTF16ToWide(default_prompt_text);
|
||||
callback_ = std::move(callback);
|
||||
|
||||
InstallMessageHook();
|
||||
hook_installed_ = true;
|
||||
|
||||
int dialog_type;
|
||||
if (message_type == content::JAVASCRIPT_DIALOG_TYPE_ALERT)
|
||||
dialog_type = IDD_ALERT;
|
||||
else if (message_type == content::JAVASCRIPT_DIALOG_TYPE_CONFIRM)
|
||||
dialog_type = IDD_CONFIRM;
|
||||
else // JAVASCRIPT_DIALOG_TYPE_PROMPT
|
||||
dialog_type = IDD_PROMPT;
|
||||
|
||||
base::FilePath file_path;
|
||||
HMODULE hModule = NULL;
|
||||
|
||||
// Try to load the dialog from the DLL.
|
||||
if (base::PathService::Get(base::DIR_MODULE, &file_path)) {
|
||||
file_path = file_path.Append(L"libcef.dll");
|
||||
hModule = ::GetModuleHandle(file_path.value().c_str());
|
||||
}
|
||||
if (!hModule)
|
||||
hModule = ::GetModuleHandle(NULL);
|
||||
DCHECK(hModule);
|
||||
|
||||
parent_win_ = GetAncestor(browser->GetWindowHandle(), GA_ROOT);
|
||||
dialog_win_ =
|
||||
CreateDialogParam(hModule, MAKEINTRESOURCE(dialog_type), parent_win_,
|
||||
DialogProc, reinterpret_cast<LPARAM>(this));
|
||||
DCHECK(dialog_win_);
|
||||
|
||||
if (!display_url.empty()) {
|
||||
// Add the display URL to the window title.
|
||||
wchar_t text[64];
|
||||
GetWindowText(dialog_win_, text, sizeof(text) / sizeof(wchar_t));
|
||||
|
||||
std::wstring new_window_text =
|
||||
std::wstring(text) + L" - " + base::UTF16ToWide(display_url);
|
||||
SetWindowText(dialog_win_, new_window_text.c_str());
|
||||
}
|
||||
|
||||
// Disable the parent window so the user can't interact with it.
|
||||
if (IsWindowEnabled(parent_win_))
|
||||
EnableWindow(parent_win_, FALSE);
|
||||
|
||||
ShowWindow(dialog_win_, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerWin::Cancel() {
|
||||
// Re-enable the parent before closing the popup to avoid focus/activation/
|
||||
// z-order issues.
|
||||
if (parent_win_ && IsWindow(parent_win_) && !IsWindowEnabled(parent_win_)) {
|
||||
EnableWindow(parent_win_, TRUE);
|
||||
parent_win_ = NULL;
|
||||
}
|
||||
|
||||
if (dialog_win_ && IsWindow(dialog_win_)) {
|
||||
SetWindowLongPtr(dialog_win_, DWLP_USER, NULL);
|
||||
DestroyWindow(dialog_win_);
|
||||
dialog_win_ = NULL;
|
||||
}
|
||||
|
||||
if (hook_installed_) {
|
||||
UninstallMessageHook();
|
||||
hook_installed_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CefJavaScriptDialogRunnerWin::CloseDialog(bool success,
|
||||
const std::wstring& user_input) {
|
||||
// Run the callback first so that RenderProcessHostImpl::IsBlocked is
|
||||
// cleared. Otherwise, RenderWidgetHostImpl::IsIgnoringInputEvents will
|
||||
// return true and RenderWidgetHostViewAura::OnWindowFocused will fail to
|
||||
// re-assign browser focus.
|
||||
std::move(callback_).Run(success, base::WideToUTF16(user_input));
|
||||
Cancel();
|
||||
}
|
||||
|
||||
// static
|
||||
LRESULT CALLBACK CefJavaScriptDialogRunnerWin::GetMsgProc(int code,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam) {
|
||||
// Mostly borrowed from http://support.microsoft.com/kb/q187988/
|
||||
// and http://www.codeproject.com/KB/atl/cdialogmessagehook.aspx.
|
||||
LPMSG msg = reinterpret_cast<LPMSG>(lparam);
|
||||
if (code >= 0 && wparam == PM_REMOVE && msg->message >= WM_KEYFIRST &&
|
||||
msg->message <= WM_KEYLAST) {
|
||||
HWND hwnd = GetActiveWindow();
|
||||
if (::IsWindow(hwnd) && ::IsDialogMessage(hwnd, msg)) {
|
||||
// The value returned from this hookproc is ignored, and it cannot
|
||||
// be used to tell Windows the message has been handled. To avoid
|
||||
// further processing, convert the message to WM_NULL before
|
||||
// returning.
|
||||
msg->hwnd = NULL;
|
||||
msg->message = WM_NULL;
|
||||
msg->lParam = 0L;
|
||||
msg->wParam = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Passes the hook information to the next hook procedure in
|
||||
// the current hook chain.
|
||||
return ::CallNextHookEx(msg_hook_, code, wparam, lparam);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefJavaScriptDialogRunnerWin::InstallMessageHook() {
|
||||
msg_hook_user_count_++;
|
||||
|
||||
// Make sure we only call this once.
|
||||
if (msg_hook_ != NULL)
|
||||
return true;
|
||||
|
||||
msg_hook_ = ::SetWindowsHookEx(WH_GETMESSAGE,
|
||||
&CefJavaScriptDialogRunnerWin::GetMsgProc,
|
||||
NULL, GetCurrentThreadId());
|
||||
DCHECK(msg_hook_ != NULL);
|
||||
return msg_hook_ != NULL;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CefJavaScriptDialogRunnerWin::UninstallMessageHook() {
|
||||
msg_hook_user_count_--;
|
||||
DCHECK_GE(msg_hook_user_count_, 0);
|
||||
|
||||
if (msg_hook_user_count_ > 0)
|
||||
return true;
|
||||
|
||||
DCHECK(msg_hook_ != NULL);
|
||||
BOOL result = ::UnhookWindowsHookEx(msg_hook_);
|
||||
DCHECK(result);
|
||||
msg_hook_ = NULL;
|
||||
|
||||
return result != FALSE;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2012 The Chromium Embedded Framework Authors.
|
||||
// Portions copyright (c) 2012 The Chromium 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_NATIVE_JAVASCRIPT_DIALOG_RUNNER_WIN_H_
|
||||
#define CEF_LIBCEF_BROWSER_NATIVE_JAVASCRIPT_DIALOG_RUNNER_WIN_H_
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "libcef/browser/javascript_dialog_runner.h"
|
||||
|
||||
class CefJavaScriptDialogRunnerWin : public CefJavaScriptDialogRunner {
|
||||
public:
|
||||
CefJavaScriptDialogRunnerWin();
|
||||
~CefJavaScriptDialogRunnerWin() override;
|
||||
|
||||
// CefJavaScriptDialogRunner methods:
|
||||
void Run(AlloyBrowserHostImpl* browser,
|
||||
content::JavaScriptDialogType message_type,
|
||||
const std::u16string& display_url,
|
||||
const std::u16string& message_text,
|
||||
const std::u16string& default_prompt_text,
|
||||
DialogClosedCallback callback) override;
|
||||
void Cancel() override;
|
||||
|
||||
private:
|
||||
void CloseDialog(bool success, const std::wstring& user_input);
|
||||
|
||||
HWND dialog_win_;
|
||||
HWND parent_win_;
|
||||
|
||||
content::JavaScriptDialogType message_type_;
|
||||
std::wstring message_text_;
|
||||
std::wstring default_prompt_text_;
|
||||
DialogClosedCallback callback_;
|
||||
|
||||
bool hook_installed_;
|
||||
|
||||
static INT_PTR CALLBACK DialogProc(HWND dialog,
|
||||
UINT message,
|
||||
WPARAM wparam,
|
||||
LPARAM lparam);
|
||||
|
||||
// Since the message loop we expect to run in isn't going to be nicely
|
||||
// calling IsDialogMessage(), we need to hook the wnd proc and call it
|
||||
// ourselves. See http://support.microsoft.com/kb/q187988/
|
||||
static bool InstallMessageHook();
|
||||
static bool UninstallMessageHook();
|
||||
static LRESULT CALLBACK GetMsgProc(int code, WPARAM wparam, LPARAM lparam);
|
||||
static HHOOK msg_hook_;
|
||||
static int msg_hook_user_count_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_NATIVE_JAVASCRIPT_DIALOG_RUNNER_WIN_H_
|
@ -235,6 +235,13 @@ void CefBrowserPlatformDelegateOsr::WasHidden(bool hidden) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CefBrowserPlatformDelegateOsr::IsHidden() const {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
return view->is_hidden();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CefBrowserPlatformDelegateOsr::NotifyScreenInfoChanged() {
|
||||
CefRenderWidgetHostViewOSR* view = GetOSRHostView();
|
||||
if (view)
|
||||
|
@ -55,6 +55,7 @@ class CefBrowserPlatformDelegateOsr
|
||||
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
bool IsWindowless() const override;
|
||||
void WasHidden(bool hidden) override;
|
||||
bool IsHidden() const override;
|
||||
void NotifyScreenInfoChanged() override;
|
||||
void Invalidate(cef_paint_element_type_t type) override;
|
||||
void SendExternalBeginFrame() override;
|
||||
|
@ -308,6 +308,8 @@ class CefRenderWidgetHostViewOSR
|
||||
|
||||
ui::TextInputType GetTextInputType();
|
||||
|
||||
bool is_hidden() const { return !is_showing_; }
|
||||
|
||||
private:
|
||||
void SetFrameRate();
|
||||
bool SetScreenInfo();
|
||||
|
@ -1,46 +0,0 @@
|
||||
// Copyright 2014 The Chromium 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/printing/constrained_window_views_client.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/notreached.h"
|
||||
#include "chrome/browser/platform_util.h"
|
||||
#include "chrome/browser/ui/browser_finder.h"
|
||||
#include "components/web_modal/web_contents_modal_dialog_host.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class CefConstrainedWindowViewsClient
|
||||
: public constrained_window::ConstrainedWindowViewsClient {
|
||||
public:
|
||||
CefConstrainedWindowViewsClient() {}
|
||||
|
||||
CefConstrainedWindowViewsClient(const CefConstrainedWindowViewsClient&) =
|
||||
delete;
|
||||
CefConstrainedWindowViewsClient& operator=(
|
||||
const CefConstrainedWindowViewsClient&) = delete;
|
||||
|
||||
~CefConstrainedWindowViewsClient() override {}
|
||||
|
||||
private:
|
||||
// ConstrainedWindowViewsClient:
|
||||
web_modal::ModalDialogHost* GetModalDialogHost(
|
||||
gfx::NativeWindow parent) override {
|
||||
NOTREACHED();
|
||||
return nullptr;
|
||||
}
|
||||
gfx::NativeView GetDialogHostView(gfx::NativeWindow parent) override {
|
||||
NOTREACHED();
|
||||
return gfx::NativeView();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
|
||||
CreateCefConstrainedWindowViewsClient() {
|
||||
return base::WrapUnique(new CefConstrainedWindowViewsClient);
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// Copyright 2014 The Chromium 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_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
||||
#define CEF_LIBCEF_BROWSER_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "components/constrained_window/constrained_window_views_client.h"
|
||||
|
||||
// Creates a ConstrainedWindowViewsClient for the Chrome environment.
|
||||
std::unique_ptr<constrained_window::ConstrainedWindowViewsClient>
|
||||
CreateCefConstrainedWindowViewsClient();
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_PRINTING_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_
|
@ -258,11 +258,6 @@ CefEventHandle CefBrowserPlatformDelegateViews::GetEventHandle(
|
||||
return native_delegate_->GetEventHandle(event);
|
||||
}
|
||||
|
||||
std::unique_ptr<CefJavaScriptDialogRunner>
|
||||
CefBrowserPlatformDelegateViews::CreateJavaScriptDialogRunner() {
|
||||
return native_delegate_->CreateJavaScriptDialogRunner();
|
||||
}
|
||||
|
||||
std::unique_ptr<CefMenuRunner>
|
||||
CefBrowserPlatformDelegateViews::CreateMenuRunner() {
|
||||
return base::WrapUnique(new CefMenuRunnerViews(browser_view_.get()));
|
||||
|
@ -61,8 +61,6 @@ class CefBrowserPlatformDelegateViews
|
||||
const content::NativeWebKeyboardEvent& event) override;
|
||||
CefEventHandle GetEventHandle(
|
||||
const content::NativeWebKeyboardEvent& event) const override;
|
||||
std::unique_ptr<CefJavaScriptDialogRunner> CreateJavaScriptDialogRunner()
|
||||
override;
|
||||
std::unique_ptr<CefMenuRunner> CreateMenuRunner() override;
|
||||
bool IsViewsHosted() const override;
|
||||
gfx::Point GetDialogPosition(const gfx::Size& size) override;
|
||||
|
@ -1,64 +0,0 @@
|
||||
// Copyright (c) 2019 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/web_contents_dialog_helper.h"
|
||||
|
||||
#include "libcef/browser/browser_platform_delegate.h"
|
||||
|
||||
#include "chrome/browser/platform_util.h"
|
||||
#include "components/web_modal/web_contents_modal_dialog_manager.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
CefWebContentsDialogHelper::CefWebContentsDialogHelper(
|
||||
content::WebContents* web_contents,
|
||||
CefBrowserPlatformDelegate* browser_delegate)
|
||||
: browser_delegate_(browser_delegate), weak_factory_(this) {
|
||||
web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents);
|
||||
web_modal::WebContentsModalDialogManager::FromWebContents(web_contents)
|
||||
->SetDelegate(this);
|
||||
}
|
||||
|
||||
base::RepeatingClosure CefWebContentsDialogHelper::GetBoundsChangedCallback() {
|
||||
return base::BindRepeating(&CefWebContentsDialogHelper::OnBoundsChanged,
|
||||
weak_factory_.GetWeakPtr());
|
||||
}
|
||||
|
||||
bool CefWebContentsDialogHelper::IsWebContentsVisible(
|
||||
content::WebContents* web_contents) {
|
||||
return platform_util::IsVisible(web_contents->GetNativeView());
|
||||
}
|
||||
|
||||
web_modal::WebContentsModalDialogHost*
|
||||
CefWebContentsDialogHelper::GetWebContentsModalDialogHost() {
|
||||
return this;
|
||||
}
|
||||
|
||||
gfx::NativeView CefWebContentsDialogHelper::GetHostView() const {
|
||||
return browser_delegate_->GetWindowWidget()->GetNativeView();
|
||||
}
|
||||
|
||||
gfx::Point CefWebContentsDialogHelper::GetDialogPosition(
|
||||
const gfx::Size& size) {
|
||||
return browser_delegate_->GetDialogPosition(size);
|
||||
}
|
||||
|
||||
gfx::Size CefWebContentsDialogHelper::GetMaximumDialogSize() {
|
||||
return browser_delegate_->GetMaximumDialogSize();
|
||||
}
|
||||
|
||||
void CefWebContentsDialogHelper::AddObserver(
|
||||
web_modal::ModalDialogHostObserver* observer) {
|
||||
if (observer && !observer_list_.HasObserver(observer))
|
||||
observer_list_.AddObserver(observer);
|
||||
}
|
||||
|
||||
void CefWebContentsDialogHelper::RemoveObserver(
|
||||
web_modal::ModalDialogHostObserver* observer) {
|
||||
observer_list_.RemoveObserver(observer);
|
||||
}
|
||||
|
||||
void CefWebContentsDialogHelper::OnBoundsChanged() {
|
||||
for (auto& observer : observer_list_)
|
||||
observer.OnPositionRequiresUpdate();
|
||||
}
|
@ -91,6 +91,7 @@ patches = [
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1677
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1679
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1700
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/3316
|
||||
#
|
||||
# Support creation of captionless windows with resizable borders.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1749
|
||||
@ -225,12 +226,21 @@ patches = [
|
||||
'name': 'chrome_browser_context_menus',
|
||||
},
|
||||
{
|
||||
# Support use of chrome dialogs with CEF runtimes.
|
||||
# Support use of chrome native dialogs with CEF runtimes.
|
||||
# - Adds support for FileSelectHelper and SelectFileDialog interception.
|
||||
# - Adds additional type filters for dialogs created via FileSelectHelper.
|
||||
# - Adds support for chaining PrintingContextLinux callbacks.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/3314
|
||||
'name': 'chrome_browser_dialogs',
|
||||
'name': 'chrome_browser_dialogs_native',
|
||||
},
|
||||
{
|
||||
# Support use of chrome Widget dialogs with CEF runtimes.
|
||||
# - Add gfx::AcceleratedWidget dialog parent argument to
|
||||
# DialogDelegate::CreateDialogWidget for CEF windowless rendering.
|
||||
# - Support nullptr gfx::NativeWindow/gfx::NativeView dialog parent for CEF
|
||||
# windowless rendering.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/3316
|
||||
'name': 'chrome_browser_dialogs_widget',
|
||||
},
|
||||
{
|
||||
# chrome: Support override of ChromeMimeHandlerViewGuestDelegate.
|
||||
|
225
patch/patches/chrome_browser_dialogs_widget.patch
Normal file
225
patch/patches/chrome_browser_dialogs_widget.patch
Normal file
@ -0,0 +1,225 @@
|
||||
diff --git chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc
|
||||
index a15902b583edc..2501a2d8ead5f 100644
|
||||
--- chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc
|
||||
+++ chrome/browser/ui/views/chrome_javascript_app_modal_view_factory_views.cc
|
||||
@@ -97,7 +97,7 @@ javascript_dialogs::AppModalDialogView* CreateViewsJavaScriptDialog(
|
||||
gfx::NativeWindow parent_window =
|
||||
controller->web_contents()->GetTopLevelNativeWindow();
|
||||
#if defined(USE_AURA)
|
||||
- if (!parent_window->GetRootWindow()) {
|
||||
+ if (parent_window && !parent_window->GetRootWindow()) {
|
||||
// When we are part of a WebContents that isn't actually being displayed
|
||||
// on the screen, we can't actually attach to it.
|
||||
parent_window = nullptr;
|
||||
diff --git components/constrained_window/constrained_window_views.cc components/constrained_window/constrained_window_views.cc
|
||||
index d662221bcc6f7..8b139e1935e29 100644
|
||||
--- components/constrained_window/constrained_window_views.cc
|
||||
+++ components/constrained_window/constrained_window_views.cc
|
||||
@@ -100,15 +100,24 @@ void UpdateModalDialogPosition(views::Widget* widget,
|
||||
if (widget->HasCapture())
|
||||
return;
|
||||
|
||||
+ // |host_view| will be nullptr with CEF windowless rendering.
|
||||
+ auto host_view = dialog_host->GetHostView();
|
||||
views::Widget* host_widget =
|
||||
- views::Widget::GetWidgetForNativeView(dialog_host->GetHostView());
|
||||
+ host_view ? views::Widget::GetWidgetForNativeView(host_view) : nullptr;
|
||||
|
||||
// If the host view is not backed by a Views::Widget, just update the widget
|
||||
// size. This can happen on MacViews under the Cocoa browser where the window
|
||||
// modal dialogs are displayed as sheets, and their position is managed by a
|
||||
// ConstrainedWindowSheetController instance.
|
||||
if (!host_widget) {
|
||||
+#if BUILDFLAG(IS_MAC)
|
||||
widget->SetSize(size);
|
||||
+#elif BUILDFLAG(IS_POSIX)
|
||||
+ // Set the bounds here instead of relying on the default behavior of
|
||||
+ // DesktopWindowTreeHostPlatform::CenterWindow which incorrectly centers
|
||||
+ // the window on the screen.
|
||||
+ widget->SetBounds(gfx::Rect(dialog_host->GetDialogPosition(size), size));
|
||||
+#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -207,7 +216,8 @@ views::Widget* CreateWebModalDialogViews(views::WidgetDelegate* dialog,
|
||||
|
||||
return views::DialogDelegate::CreateDialogWidget(
|
||||
dialog, nullptr,
|
||||
- manager->delegate()->GetWebContentsModalDialogHost()->GetHostView());
|
||||
+ manager->delegate()->GetWebContentsModalDialogHost()->GetHostView(),
|
||||
+ manager->delegate()->GetWebContentsModalDialogHost()->GetHostWidget());
|
||||
}
|
||||
|
||||
views::Widget* CreateBrowserModalDialogViews(
|
||||
@@ -224,8 +234,13 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
|
||||
|
||||
gfx::NativeView parent_view =
|
||||
parent ? CurrentClient()->GetDialogHostView(parent) : nullptr;
|
||||
+ // Use with CEF windowless rendering.
|
||||
+ gfx::AcceleratedWidget parent_widget =
|
||||
+ parent ? gfx::kNullAcceleratedWidget :
|
||||
+ CurrentClient()->GetModalDialogHost(parent)->GetHostWidget();
|
||||
views::Widget* widget =
|
||||
- views::DialogDelegate::CreateDialogWidget(dialog, nullptr, parent_view);
|
||||
+ views::DialogDelegate::CreateDialogWidget(dialog, nullptr, parent_view,
|
||||
+ parent_widget);
|
||||
|
||||
bool requires_positioning = dialog->use_custom_frame();
|
||||
|
||||
@@ -238,8 +253,7 @@ views::Widget* CreateBrowserModalDialogViews(views::DialogDelegate* dialog,
|
||||
if (!requires_positioning)
|
||||
return widget;
|
||||
|
||||
- ModalDialogHost* host =
|
||||
- parent ? CurrentClient()->GetModalDialogHost(parent) : nullptr;
|
||||
+ ModalDialogHost* host = CurrentClient()->GetModalDialogHost(parent);
|
||||
if (host) {
|
||||
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 ac015f82f720d..80d11897e5d6d 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(
|
||||
if (host_) {
|
||||
host_->AddObserver(this);
|
||||
|
||||
- for (auto* widget : observed_widgets_) {
|
||||
- views::Widget::ReparentNativeView(widget->GetNativeView(),
|
||||
- host_->GetHostView());
|
||||
+ // |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);
|
||||
+ }
|
||||
}
|
||||
|
||||
OnPositionRequiresUpdate();
|
||||
diff --git components/web_modal/modal_dialog_host.h components/web_modal/modal_dialog_host.h
|
||||
index b220ddc72bab2..2a9a35b97f189 100644
|
||||
--- components/web_modal/modal_dialog_host.h
|
||||
+++ components/web_modal/modal_dialog_host.h
|
||||
@@ -34,6 +34,10 @@ class WEB_MODAL_EXPORT ModalDialogHost {
|
||||
|
||||
// Returns the view against which the dialog is positioned and parented.
|
||||
virtual gfx::NativeView GetHostView() const = 0;
|
||||
+ // Returns the widget against which the dialog is positioned and parented.
|
||||
+ // Used with CEF windowless rendering.
|
||||
+ virtual gfx::AcceleratedWidget GetHostWidget() const {
|
||||
+ return gfx::kNullAcceleratedWidget; }
|
||||
// Gets the position for the dialog in coordinates relative to the host view.
|
||||
virtual gfx::Point GetDialogPosition(const gfx::Size& size) = 0;
|
||||
// Returns whether a dialog currently about to be shown should be activated.
|
||||
diff --git ui/views/window/dialog_delegate.cc ui/views/window/dialog_delegate.cc
|
||||
index fcf0b05964557..3cac0c96d7ca7 100644
|
||||
--- ui/views/window/dialog_delegate.cc
|
||||
+++ ui/views/window/dialog_delegate.cc
|
||||
@@ -60,10 +60,12 @@ DialogDelegate::DialogDelegate() {
|
||||
// static
|
||||
Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate,
|
||||
gfx::NativeWindow context,
|
||||
- gfx::NativeView parent) {
|
||||
+ gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget) {
|
||||
views::Widget* widget = new views::Widget;
|
||||
views::Widget::InitParams params =
|
||||
- GetDialogWidgetInitParams(delegate, context, parent, gfx::Rect());
|
||||
+ GetDialogWidgetInitParams(delegate, context, parent, gfx::Rect(),
|
||||
+ parent_widget);
|
||||
widget->Init(std::move(params));
|
||||
return widget;
|
||||
}
|
||||
@@ -72,22 +74,24 @@ Widget* DialogDelegate::CreateDialogWidget(WidgetDelegate* delegate,
|
||||
Widget* DialogDelegate::CreateDialogWidget(
|
||||
std::unique_ptr<WidgetDelegate> delegate,
|
||||
gfx::NativeWindow context,
|
||||
- gfx::NativeView parent) {
|
||||
+ gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget) {
|
||||
DCHECK(delegate->owned_by_widget());
|
||||
- return CreateDialogWidget(delegate.release(), context, parent);
|
||||
+ return CreateDialogWidget(delegate.release(), context, parent, parent_widget);
|
||||
}
|
||||
|
||||
// static
|
||||
-bool DialogDelegate::CanSupportCustomFrame(gfx::NativeView parent) {
|
||||
+bool DialogDelegate::CanSupportCustomFrame(gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget) {
|
||||
#if (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && \
|
||||
BUILDFLAG(ENABLE_DESKTOP_AURA)
|
||||
// The new style doesn't support unparented dialogs on Linux desktop.
|
||||
- return parent != nullptr;
|
||||
+ return parent != nullptr || parent_widget != gfx::kNullAcceleratedWidget;
|
||||
#else
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
// The new style doesn't support unparented dialogs on Windows Classic themes.
|
||||
if (!ui::win::IsAeroGlassEnabled())
|
||||
- return parent != nullptr;
|
||||
+ return parent != nullptr || parent_widget != gfx::kNullAcceleratedWidget;
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
@@ -98,14 +102,15 @@ Widget::InitParams DialogDelegate::GetDialogWidgetInitParams(
|
||||
WidgetDelegate* delegate,
|
||||
gfx::NativeWindow context,
|
||||
gfx::NativeView parent,
|
||||
- const gfx::Rect& bounds) {
|
||||
+ const gfx::Rect& bounds,
|
||||
+ gfx::AcceleratedWidget parent_widget) {
|
||||
views::Widget::InitParams params;
|
||||
params.delegate = delegate;
|
||||
params.bounds = bounds;
|
||||
DialogDelegate* dialog = delegate->AsDialogDelegate();
|
||||
|
||||
if (dialog)
|
||||
- dialog->params_.custom_frame &= CanSupportCustomFrame(parent);
|
||||
+ dialog->params_.custom_frame &= CanSupportCustomFrame(parent, parent_widget);
|
||||
|
||||
if (!dialog || dialog->use_custom_frame()) {
|
||||
params.opacity = Widget::InitParams::WindowOpacity::kTranslucent;
|
||||
@@ -118,6 +123,7 @@ Widget::InitParams DialogDelegate::GetDialogWidgetInitParams(
|
||||
}
|
||||
params.context = context;
|
||||
params.parent = parent;
|
||||
+ params.parent_widget = parent_widget;
|
||||
#if !BUILDFLAG(IS_APPLE)
|
||||
// Web-modal (ui::MODAL_TYPE_CHILD) dialogs with parents are marked as child
|
||||
// widgets to prevent top-level window behavior (independent movement, etc).
|
||||
diff --git ui/views/window/dialog_delegate.h ui/views/window/dialog_delegate.h
|
||||
index 2575e99e67586..29fc582388bbd 100644
|
||||
--- ui/views/window/dialog_delegate.h
|
||||
+++ ui/views/window/dialog_delegate.h
|
||||
@@ -94,13 +94,18 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
|
||||
// your use case.
|
||||
static Widget* CreateDialogWidget(std::unique_ptr<WidgetDelegate> delegate,
|
||||
gfx::NativeWindow context,
|
||||
- gfx::NativeView parent);
|
||||
+ gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget =
|
||||
+ gfx::kNullAcceleratedWidget);
|
||||
static Widget* CreateDialogWidget(WidgetDelegate* delegate,
|
||||
gfx::NativeWindow context,
|
||||
- gfx::NativeView parent);
|
||||
+ gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget =
|
||||
+ gfx::kNullAcceleratedWidget);
|
||||
|
||||
// Whether using custom dialog frame is supported for this dialog.
|
||||
- static bool CanSupportCustomFrame(gfx::NativeView parent);
|
||||
+ static bool CanSupportCustomFrame(gfx::NativeView parent,
|
||||
+ gfx::AcceleratedWidget parent_widget);
|
||||
|
||||
// Returns the dialog widget InitParams for a given |context| or |parent|.
|
||||
// If |bounds| is not empty, used to initially place the dialog, otherwise
|
||||
@@ -108,7 +113,9 @@ class VIEWS_EXPORT DialogDelegate : public WidgetDelegate {
|
||||
static Widget::InitParams GetDialogWidgetInitParams(WidgetDelegate* delegate,
|
||||
gfx::NativeWindow context,
|
||||
gfx::NativeView parent,
|
||||
- const gfx::Rect& bounds);
|
||||
+ const gfx::Rect& bounds,
|
||||
+ gfx::AcceleratedWidget parent_widget =
|
||||
+ gfx::kNullAcceleratedWidget);
|
||||
|
||||
// Returns a mask specifying which of the available DialogButtons are visible
|
||||
// for the dialog.
|
@ -404,10 +404,23 @@ index b3a3efd0e526f..8590a98eaf0b2 100644
|
||||
if (native_widget_delegate->IsDialogBox()) {
|
||||
*style |= DS_MODALFRAME;
|
||||
diff --git ui/views/win/hwnd_message_handler.cc ui/views/win/hwnd_message_handler.cc
|
||||
index 0a34478e9cb44..bf9059edbd634 100644
|
||||
index 0a34478e9cb44..e61fca5b6e525 100644
|
||||
--- ui/views/win/hwnd_message_handler.cc
|
||||
+++ ui/views/win/hwnd_message_handler.cc
|
||||
@@ -3176,10 +3176,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
@@ -796,7 +796,11 @@ bool HWNDMessageHandler::IsVisible() const {
|
||||
}
|
||||
|
||||
bool HWNDMessageHandler::IsActive() const {
|
||||
- return GetActiveWindow() == hwnd();
|
||||
+ // This active state is checked via FocusManager::SetFocusedViewWithReason.
|
||||
+ // With CEF external parent hwnd() may be a child window, whereas
|
||||
+ // GetActiveWindow() will return the root window, so make sure that we always
|
||||
+ // compare root windows.
|
||||
+ return GetActiveWindow() == GetAncestor(hwnd(), GA_ROOT);
|
||||
}
|
||||
|
||||
bool HWNDMessageHandler::IsMinimized() const {
|
||||
@@ -3176,10 +3180,13 @@ LRESULT HWNDMessageHandler::HandleMouseEventInternal(UINT message,
|
||||
} else if (event.type() == ui::ET_MOUSEWHEEL) {
|
||||
ui::MouseWheelEvent mouse_wheel_event(msg);
|
||||
// Reroute the mouse wheel to the window under the pointer if applicable.
|
||||
|
@ -271,31 +271,45 @@ ClientHandler::ClientHandler(Delegate* delegate,
|
||||
offline_ = command_line->HasSwitch(switches::kOffline);
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Optionally use the client-provided dialog implementation.
|
||||
bool use_client_dialogs =
|
||||
// Optionally use the client-provided GTK dialogs.
|
||||
const bool use_client_dialogs =
|
||||
command_line->HasSwitch(switches::kUseClientDialogs);
|
||||
|
||||
if (!use_client_dialogs &&
|
||||
command_line->HasSwitch(switches::kMultiThreadedMessageLoop)) {
|
||||
// Default dialogs are not supported in combination with
|
||||
// multi-threaded-message-loop because Chromium doesn't support GDK threads
|
||||
// internally.
|
||||
// Determine if the client-provided GTK dialogs can/should be used.
|
||||
bool require_client_dialogs = false;
|
||||
bool support_client_dialogs = true;
|
||||
|
||||
if (command_line->HasSwitch(switches::kMultiThreadedMessageLoop)) {
|
||||
// Default/internal GTK dialogs are not supported in combination with
|
||||
// multi-threaded-message-loop because Chromium doesn't support GDK threads.
|
||||
// This does not apply to the JS dialogs which use Views instead of GTK.
|
||||
if (!use_client_dialogs) {
|
||||
LOG(WARNING) << "Client dialogs must be used in combination with "
|
||||
"multi-threaded-message-loop.";
|
||||
use_client_dialogs = true;
|
||||
}
|
||||
|
||||
if (use_client_dialogs && MainContext::Get()->UseViews()) {
|
||||
// Client dialogs cannot be used in combination with Views because the
|
||||
// implementation of ClientDialogHandlerGtk requires a top-level GtkWindow.
|
||||
LOG(ERROR) << "Client dialogs cannot be used in combination with Views.";
|
||||
use_client_dialogs = false;
|
||||
}
|
||||
require_client_dialogs = true;
|
||||
}
|
||||
|
||||
if (MainContext::Get()->UseViews()) {
|
||||
// Client-provided GTK dialogs cannot be used in combination with Views
|
||||
// because the implementation of ClientDialogHandlerGtk requires a top-level
|
||||
// GtkWindow.
|
||||
if (use_client_dialogs) {
|
||||
dialog_handler_ = new ClientDialogHandlerGtk();
|
||||
LOG(ERROR) << "Client dialogs cannot be used in combination with Views.";
|
||||
}
|
||||
support_client_dialogs = false;
|
||||
}
|
||||
|
||||
if (support_client_dialogs) {
|
||||
if (use_client_dialogs) {
|
||||
js_dialog_handler_ = new ClientDialogHandlerGtk();
|
||||
}
|
||||
if (use_client_dialogs || require_client_dialogs) {
|
||||
file_dialog_handler_ = js_dialog_handler_ ? js_dialog_handler_
|
||||
: new ClientDialogHandlerGtk();
|
||||
print_handler_ = new ClientPrintHandlerGtk();
|
||||
}
|
||||
}
|
||||
#endif // defined(OS_LINUX)
|
||||
}
|
||||
|
||||
|
@ -121,10 +121,10 @@ class ClientHandler : public CefClient,
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
CefRefPtr<CefDialogHandler> GetDialogHandler() override {
|
||||
return dialog_handler_;
|
||||
return file_dialog_handler_;
|
||||
}
|
||||
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() override {
|
||||
return dialog_handler_;
|
||||
return js_dialog_handler_;
|
||||
}
|
||||
CefRefPtr<CefPrintHandler> GetPrintHandler() override {
|
||||
return print_handler_;
|
||||
@ -389,8 +389,9 @@ class ClientHandler : public CefClient,
|
||||
bool download_favicon_images_;
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
// Custom dialog handler for GTK.
|
||||
CefRefPtr<ClientDialogHandlerGtk> dialog_handler_;
|
||||
// Custom dialog handlers for GTK.
|
||||
CefRefPtr<ClientDialogHandlerGtk> file_dialog_handler_;
|
||||
CefRefPtr<ClientDialogHandlerGtk> js_dialog_handler_;
|
||||
CefRefPtr<ClientPrintHandlerGtk> print_handler_;
|
||||
#endif
|
||||
|
||||
|
@ -529,6 +529,10 @@ void RootWindowViews::NotifyViewsWindowActivated() {
|
||||
void RootWindowViews::NotifyDestroyedIfDone() {
|
||||
// Notify once both the window and the browser have been destroyed.
|
||||
if (window_destroyed_ && browser_destroyed_) {
|
||||
// The delegate may be holding the last reference to |this|, so take a
|
||||
// reference here to keep |this| alive until after the method completes.
|
||||
scoped_refptr<RootWindow> self = this;
|
||||
|
||||
delegate_->OnRootWindowDestroyed(this);
|
||||
if (!config_->close_callback.is_null())
|
||||
std::move(config_->close_callback).Run();
|
||||
|
Reference in New Issue
Block a user