| Index: components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
|
| diff --git a/components/constrained_window/native_web_contents_modal_dialog_manager_views.cc b/components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
|
| index 45e3a43e49088650c3d330cc1b27303e6fcf5329..8254ddf7e73f7754d8310018b4d2f884a43bc70f 100644
|
| --- a/components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
|
| +++ b/components/constrained_window/native_web_contents_modal_dialog_manager_views.cc
|
| @@ -9,6 +9,7 @@
|
| #include "components/constrained_window/constrained_window_views.h"
|
| #include "components/web_modal/web_contents_modal_dialog_host.h"
|
| #include "components/web_modal/web_contents_modal_dialog_manager.h"
|
| +#include "ui/base/accelerators/accelerator.h"
|
| #include "ui/gfx/geometry/point.h"
|
| #include "ui/gfx/geometry/size.h"
|
| #include "ui/views/border.h"
|
| @@ -19,10 +20,13 @@
|
|
|
| #if defined(USE_AURA)
|
| #include "ui/aura/client/aura_constants.h"
|
| +#include "ui/aura/client/window_tree_client.h"
|
| #include "ui/aura/window.h"
|
| +#include "ui/aura/window_observer.h"
|
| #include "ui/wm/core/visibility_controller.h"
|
| #include "ui/wm/core/window_animations.h"
|
| #include "ui/wm/core/window_modality_controller.h"
|
| +#include "ui/wm/core/window_util.h"
|
| #endif
|
|
|
| using web_modal::SingleWebContentsDialogManager;
|
| @@ -35,12 +39,18 @@ namespace constrained_window {
|
| NativeWebContentsModalDialogManagerViews::
|
| NativeWebContentsModalDialogManagerViews(
|
| gfx::NativeWindow dialog,
|
| - SingleWebContentsDialogManagerDelegate* native_delegate)
|
| + SingleWebContentsDialogManagerDelegate* native_delegate,
|
| + bool is_toplevel,
|
| + ui::AcceleratorTarget* target)
|
| : native_delegate_(native_delegate),
|
| dialog_(dialog),
|
| host_(NULL),
|
| - host_destroying_(false) {
|
| - ManageDialog();
|
| + host_destroying_(false),
|
| + target_(target) {
|
| +#if !defined(USE_AURA)
|
| + target_ = NULL;
|
| +#endif
|
| + ManageDialog(is_toplevel);
|
| }
|
|
|
| NativeWebContentsModalDialogManagerViews::
|
| @@ -48,13 +58,31 @@ NativeWebContentsModalDialogManagerViews::
|
| if (host_)
|
| host_->RemoveObserver(this);
|
|
|
| +#if defined(USE_AURA)
|
| + if (host_ && host_->GetHostView() && host_->GetHostView()->HasObserver(this))
|
| + host_->GetHostView()->RemoveObserver(this);
|
| +#endif
|
| +
|
| for (std::set<views::Widget*>::iterator it = observed_widgets_.begin();
|
| it != observed_widgets_.end(); ++it) {
|
| (*it)->RemoveObserver(this);
|
| }
|
| +
|
| +#if defined(USE_AURA)
|
| + if (host_ && dialog() &&
|
| + !!dialog()->GetNativeWindowProperty(wm::kAllowTransientParentEventsKey)) {
|
| + views::Widget * parent_widget = views::Widget::GetWidgetForNativeView(
|
| + host_->GetHostView());
|
| + if (parent_widget && parent_widget->GetFocusManager()) {
|
| + parent_widget->GetFocusManager()->UnregisterAccelerator(
|
| + ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE), target_);
|
| + }
|
| + }
|
| +#endif
|
| }
|
|
|
| -void NativeWebContentsModalDialogManagerViews::ManageDialog() {
|
| +void NativeWebContentsModalDialogManagerViews::ManageDialog(
|
| + bool is_toplevel) {
|
| views::Widget* widget = GetWidget(dialog());
|
| widget->AddObserver(this);
|
| observed_widgets_.insert(widget);
|
| @@ -68,17 +96,29 @@ void NativeWebContentsModalDialogManagerViews::ManageDialog() {
|
| wm::SetWindowVisibilityAnimationType(
|
| widget->GetNativeWindow(), wm::WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE);
|
|
|
| - gfx::NativeView parent = widget->GetNativeView()->parent();
|
| - wm::SetChildWindowVisibilityChangesAnimated(parent);
|
| - // No animations should get performed on the window since that will re-order
|
| - // the window stack which will then cause many problems.
|
| - if (parent && parent->parent()) {
|
| - parent->parent()->SetProperty(aura::client::kAnimationsDisabledKey, true);
|
| + if (is_toplevel) {
|
| + gfx::NativeView transient_parent =
|
| + wm::GetTransientParent(widget->GetNativeWindow());
|
| + wm::SetChildWindowVisibilityChangesAnimated(
|
| + widget->GetNativeView()->parent());
|
| + if (transient_parent && transient_parent->parent()) {
|
| + transient_parent->parent()->SetProperty(
|
| + aura::client::kAnimationsDisabledKey, true);
|
| + }
|
| + widget->SetNativeWindowProperty(wm::kAllowTransientParentEventsKey,
|
| + reinterpret_cast<void*>(true));
|
| + } else {
|
| + gfx::NativeView parent = widget->GetNativeView()->parent();
|
| + wm::SetChildWindowVisibilityChangesAnimated(parent);
|
| + // No animations should get performed on the window since that will re-order
|
| + // the window stack which will then cause many problems.
|
| + if (parent && parent->parent()) {
|
| + parent->parent()->SetProperty(aura::client::kAnimationsDisabledKey, true);
|
| + }
|
| + wm::SetModalParent(widget->GetNativeWindow(),
|
| + native_delegate_->GetWebContents()->GetNativeView());
|
| }
|
| -
|
| - wm::SetModalParent(widget->GetNativeWindow(),
|
| - native_delegate_->GetWebContents()->GetNativeView());
|
| -#endif
|
| +#endif // defined(USE_AURA)
|
| }
|
|
|
| // SingleWebContentsDialogManager:
|
| @@ -94,8 +134,10 @@ void NativeWebContentsModalDialogManagerViews::Show() {
|
| #if defined(USE_AURA)
|
| std::unique_ptr<wm::SuspendChildWindowVisibilityAnimations> suspend;
|
| if (shown_widgets_.find(widget) != shown_widgets_.end()) {
|
| - suspend.reset(new wm::SuspendChildWindowVisibilityAnimations(
|
| - widget->GetNativeWindow()->parent()));
|
| + if (!widget->GetNativeWindowProperty(wm::kAllowTransientParentEventsKey)) {
|
| + suspend.reset(new wm::SuspendChildWindowVisibilityAnimations(
|
| + widget->GetNativeWindow()->parent()));
|
| + }
|
| }
|
| #endif
|
| ShowWidget(widget);
|
| @@ -114,7 +156,7 @@ void NativeWebContentsModalDialogManagerViews::Hide() {
|
| #if defined(USE_AURA)
|
| std::unique_ptr<wm::SuspendChildWindowVisibilityAnimations> suspend;
|
| suspend.reset(new wm::SuspendChildWindowVisibilityAnimations(
|
| - widget->GetNativeWindow()->parent()));
|
| + widget->GetNativeWindow()->parent()));
|
| #endif
|
| HideWidget(widget);
|
| }
|
| @@ -150,6 +192,10 @@ void NativeWebContentsModalDialogManagerViews::OnPositionRequiresUpdate() {
|
|
|
| void NativeWebContentsModalDialogManagerViews::OnHostDestroying() {
|
| host_->RemoveObserver(this);
|
| +#if defined(USE_AURA)
|
| + if (host_->GetHostView() && host_->GetHostView()->HasObserver(this))
|
| + host_->GetHostView()->RemoveObserver(this);
|
| +#endif
|
| host_ = NULL;
|
| host_destroying_ = true;
|
| }
|
| @@ -168,9 +214,35 @@ void NativeWebContentsModalDialogManagerViews::OnWidgetDestroying(
|
|
|
| void NativeWebContentsModalDialogManagerViews::HostChanged(
|
| WebContentsModalDialogHost* new_host) {
|
| +#if defined(USE_AURA)
|
| + if (new_host == host_ ||
|
| + (new_host && !new_host->GetHostView()->GetRootWindow()))
|
| + // This happens sometimes in testing and will cause a crash.
|
| + return;
|
| +#endif
|
| if (host_)
|
| host_->RemoveObserver(this);
|
|
|
| + // Remove window observer
|
| +#if defined(USE_AURA)
|
| + if (host_ && host_->GetHostView() && host_->GetHostView()->HasObserver(this))
|
| + host_->GetHostView()->RemoveObserver(this);
|
| +
|
| + bool toplevel = !!(dialog()->GetNativeWindowProperty(
|
| + wm::kAllowTransientParentEventsKey));
|
| +
|
| + // Remove accelerators so that web contents don't pick up accelerators on
|
| + // other hosts
|
| + if (host_ && toplevel) {
|
| + views::Widget * parent_widget = views::Widget::GetWidgetForNativeView(
|
| + host_->GetHostView());
|
| + if (parent_widget && parent_widget->GetFocusManager()) {
|
| + parent_widget->GetFocusManager()->UnregisterAccelerator(
|
| + ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE), target_);
|
| + }
|
| + }
|
| +#endif
|
| +
|
| host_ = new_host;
|
|
|
| // |host_| may be null during WebContents destruction or Win32 tab dragging.
|
| @@ -179,10 +251,38 @@ void NativeWebContentsModalDialogManagerViews::HostChanged(
|
|
|
| for (std::set<views::Widget*>::iterator it = observed_widgets_.begin();
|
| it != observed_widgets_.end(); ++it) {
|
| - views::Widget::ReparentNativeView((*it)->GetNativeView(),
|
| - host_->GetHostView());
|
| +#if defined(USE_AURA)
|
| + bool widget_toplevel = !!((*it)->GetNativeWindowProperty(
|
| + wm::kAllowTransientParentEventsKey));
|
| +#else
|
| + bool widget_toplevel = false;
|
| +#endif
|
| + if(widget_toplevel) {
|
| +#if defined(USE_AURA)
|
| + if ((*it)->GetNativeView()->parent())
|
| + (*it)->GetNativeView()->parent()->RemoveChild((*it)->GetNativeView());
|
| + wm::AddTransientChild(host_->GetHostView(), (*it)->GetNativeView());
|
| + aura::client::ParentWindowWithContext(
|
| + (*it)->GetNativeView(), host_->GetHostView()->GetRootWindow(),
|
| + (*it)->GetNativeView()->bounds());
|
| +#endif
|
| + } else {
|
| + views::Widget::ReparentNativeView((*it)->GetNativeView(),
|
| + host_->GetHostView());
|
| + }
|
| }
|
| -
|
| +#if defined(USE_AURA)
|
| + // If there are top level widgets, need to register the accelerator and set
|
| + // the window observer
|
| + if (toplevel) {
|
| + host_->GetHostView()->AddObserver(this);
|
| + views::Widget * parent_widget = views::Widget::GetWidgetForNativeView(
|
| + host_->GetHostView());
|
| + parent_widget->GetFocusManager()->RegisterAccelerator(
|
| + ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE),
|
| + ui::AcceleratorManager::kNormalPriority, target_);
|
| + }
|
| +#endif
|
| OnPositionRequiresUpdate();
|
| }
|
| }
|
| @@ -211,23 +311,76 @@ views::Widget* NativeWebContentsModalDialogManagerViews::GetWidget(
|
| return widget;
|
| }
|
|
|
| +void NativeWebContentsModalDialogManagerViews::
|
| + OnNonClippedPositionRequiresUpdate() {
|
| + DCHECK(host_);
|
| +#if defined(USE_AURA)
|
| + for (std::set<views::Widget*>::iterator it = observed_widgets_.begin();
|
| + it != observed_widgets_.end(); ++it) {
|
| + if (!!((*it)->GetNativeWindowProperty(wm::kAllowTransientParentEventsKey)))
|
| + constrained_window::UpdateWebContentsModalDialogPosition(*it, host_);
|
| + }
|
| +#endif
|
| +}
|
| +
|
| void NativeWebContentsModalDialogManagerViews::WidgetClosing(
|
| views::Widget* widget) {
|
| #if defined(USE_AURA)
|
| - gfx::NativeView view = widget->GetNativeView()->parent();
|
| - // Allow the parent to animate again.
|
| - if (view && view->parent())
|
| - view->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
|
| + if (!!widget->GetNativeWindowProperty(wm::kAllowTransientParentEventsKey)) {
|
| + gfx::NativeWindow parent =
|
| + wm::GetTransientParent(widget->GetNativeWindow());
|
| + if (parent && parent->parent())
|
| + parent->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
|
| + } else {
|
| + gfx::NativeView view = widget->GetNativeView()->parent();
|
| + // Allow the parent to animate again.
|
| + if (view && view->parent())
|
| + view->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
|
| + }
|
| #endif
|
| widget->RemoveObserver(this);
|
| observed_widgets_.erase(widget);
|
|
|
| #if defined(USE_AURA)
|
| shown_widgets_.erase(widget);
|
| + if (host_ && !!widget->GetNativeWindowProperty(
|
| + wm::kAllowTransientParentEventsKey))
|
| + wm::RemoveTransientChild(host_->GetHostView(), widget->GetNativeView());
|
| #endif
|
|
|
| // Will cause this object to be deleted.
|
| native_delegate_->WillClose(widget->GetNativeWindow());
|
| }
|
|
|
| +#if defined(USE_AURA)
|
| +void NativeWebContentsModalDialogManagerViews::OnWindowBoundsChanged(
|
| + aura::Window* window,
|
| + const gfx::Rect& old_bounds,
|
| + const gfx::Rect& new_bounds) {
|
| + if (window != host_->GetHostView())
|
| + return;
|
| + OnNonClippedPositionRequiresUpdate();
|
| +}
|
| +
|
| +// Not sure if this is needed or not.
|
| +void NativeWebContentsModalDialogManagerViews::OnWindowRemovingFromRootWindow(
|
| + aura::Window* window,
|
| + aura::Window* new_root) {
|
| + if (window != host_->GetHostView())
|
| + return;
|
| + LOG(ERROR) << "Window removing from root window";
|
| + for (std::set<views::Widget*>::iterator it = observed_widgets_.begin();
|
| + it != observed_widgets_.end(); ++it) {
|
| + if (!!((*it)->GetNativeWindowProperty(
|
| + wm::kAllowTransientParentEventsKey)))
|
| + aura::client::ParentWindowWithContext((*it)->GetNativeView(),
|
| + host_->GetHostView()->GetRootWindow(), (*it)->GetNativeView()->bounds());
|
| + }
|
| +}
|
| +
|
| +void NativeWebContentsModalDialogManagerViews::OnWindowDestroying(
|
| + aura::Window* window) {
|
| + window->RemoveObserver(this);
|
| +}
|
| +#endif
|
| } // namespace constrained_window
|
|
|