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:
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.
|
Reference in New Issue
Block a user