native_web_contents_modal_dialog_manager_views.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/constrained_window/native_web_contents_modal_dialog_manager_views.h"
  5. #include <memory>
  6. #include "components/constrained_window/constrained_window_views.h"
  7. #include "components/web_modal/web_contents_modal_dialog_host.h"
  8. #include "components/web_modal/web_contents_modal_dialog_manager.h"
  9. #include "ui/gfx/geometry/point.h"
  10. #include "ui/gfx/geometry/size.h"
  11. #include "ui/views/border.h"
  12. #include "ui/views/widget/widget.h"
  13. #include "ui/views/widget/widget_delegate.h"
  14. #include "ui/views/window/dialog_delegate.h"
  15. #include "ui/views/window/non_client_view.h"
  16. #if defined(USE_AURA)
  17. #include "ui/aura/client/aura_constants.h"
  18. #include "ui/aura/window.h"
  19. #include "ui/wm/core/visibility_controller.h"
  20. #include "ui/wm/core/window_animations.h"
  21. #include "ui/wm/core/window_modality_controller.h"
  22. #endif
  23. using web_modal::SingleWebContentsDialogManager;
  24. using web_modal::SingleWebContentsDialogManagerDelegate;
  25. using web_modal::WebContentsModalDialogHost;
  26. using web_modal::ModalDialogHostObserver;
  27. namespace constrained_window {
  28. NativeWebContentsModalDialogManagerViews::
  29. NativeWebContentsModalDialogManagerViews(
  30. gfx::NativeWindow dialog,
  31. SingleWebContentsDialogManagerDelegate* native_delegate)
  32. : native_delegate_(native_delegate), dialog_(dialog) {
  33. ManageDialog();
  34. }
  35. NativeWebContentsModalDialogManagerViews::
  36. ~NativeWebContentsModalDialogManagerViews() {
  37. if (host_)
  38. host_->RemoveObserver(this);
  39. for (auto* widget : observed_widgets_)
  40. widget->RemoveObserver(this);
  41. CHECK(!IsInObserverList());
  42. }
  43. void NativeWebContentsModalDialogManagerViews::ManageDialog() {
  44. views::Widget* widget = GetWidget(dialog());
  45. widget->AddObserver(this);
  46. observed_widgets_.insert(widget);
  47. widget->set_movement_disabled(true);
  48. #if defined(USE_AURA)
  49. // TODO(wittman): remove once the new visual style is complete
  50. widget->GetNativeWindow()->SetProperty(aura::client::kConstrainedWindowKey,
  51. true);
  52. wm::SetWindowVisibilityAnimationType(
  53. widget->GetNativeWindow(), wm::WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE);
  54. gfx::NativeView parent = widget->GetNativeView()->parent();
  55. wm::SetChildWindowVisibilityChangesAnimated(parent);
  56. // No animations should get performed on the window since that will re-order
  57. // the window stack which will then cause many problems.
  58. if (parent->parent()) {
  59. parent->parent()->SetProperty(aura::client::kAnimationsDisabledKey, true);
  60. }
  61. wm::SetModalParent(widget->GetNativeWindow(),
  62. native_delegate_->GetWebContents()->GetNativeView());
  63. #endif
  64. }
  65. // SingleWebContentsDialogManager:
  66. void NativeWebContentsModalDialogManagerViews::Show() {
  67. // The host destroying means the dialogs will be destroyed in short order.
  68. // Avoid showing dialogs at this point as the necessary native window
  69. // services may not be present.
  70. if (host_destroying_)
  71. return;
  72. views::Widget* widget = GetWidget(dialog());
  73. #if defined(USE_AURA)
  74. std::unique_ptr<wm::SuspendChildWindowVisibilityAnimations> suspend;
  75. if (shown_widgets_.find(widget) != shown_widgets_.end()) {
  76. suspend = std::make_unique<wm::SuspendChildWindowVisibilityAnimations>(
  77. widget->GetNativeWindow()->parent());
  78. }
  79. #endif
  80. CHECK(host_);
  81. constrained_window::UpdateWebContentsModalDialogPosition(widget, host_);
  82. if (host_->ShouldActivateDialog()) {
  83. widget->Show();
  84. Focus();
  85. } else {
  86. widget->ShowInactive();
  87. }
  88. #if defined(USE_AURA)
  89. // TODO(pkotwicz): Control the z-order of the constrained dialog via
  90. // views::kHostViewKey. We will need to ensure that the parent window's
  91. // shadows are below the constrained dialog in z-order when we do this.
  92. shown_widgets_.insert(widget);
  93. #endif
  94. #if !defined(USE_AURA)
  95. // Don't re-animate when switching tabs. Note this is done on Mac only after
  96. // the initial Show() call above, and then "sticks" for later calls.
  97. // TODO(tapted): Consolidate this codepath with Aura.
  98. widget->SetVisibilityAnimationTransition(views::Widget::ANIMATE_HIDE);
  99. #endif
  100. }
  101. void NativeWebContentsModalDialogManagerViews::Hide() {
  102. views::Widget* widget = GetWidget(dialog());
  103. #if defined(USE_AURA)
  104. auto suspend = std::make_unique<wm::SuspendChildWindowVisibilityAnimations>(
  105. widget->GetNativeWindow()->parent());
  106. #endif
  107. widget->Hide();
  108. }
  109. void NativeWebContentsModalDialogManagerViews::Close() {
  110. GetWidget(dialog())->Close();
  111. }
  112. void NativeWebContentsModalDialogManagerViews::Focus() {
  113. views::Widget* widget = GetWidget(dialog());
  114. if (widget->widget_delegate() &&
  115. widget->widget_delegate()->GetInitiallyFocusedView())
  116. widget->widget_delegate()->GetInitiallyFocusedView()->RequestFocus();
  117. #if defined(USE_AURA)
  118. // We don't necessarily have a RootWindow yet.
  119. if (widget->GetNativeView()->GetRootWindow())
  120. widget->GetNativeView()->Focus();
  121. #endif
  122. }
  123. void NativeWebContentsModalDialogManagerViews::Pulse() {}
  124. // web_modal::ModalDialogHostObserver:
  125. void NativeWebContentsModalDialogManagerViews::OnPositionRequiresUpdate() {
  126. DCHECK(host_);
  127. for (auto* widget : observed_widgets_)
  128. constrained_window::UpdateWebContentsModalDialogPosition(widget, host_);
  129. }
  130. void NativeWebContentsModalDialogManagerViews::OnHostDestroying() {
  131. host_->RemoveObserver(this);
  132. host_ = nullptr;
  133. host_destroying_ = true;
  134. }
  135. // views::WidgetObserver:
  136. void NativeWebContentsModalDialogManagerViews::OnWidgetClosing(
  137. views::Widget* widget) {
  138. WidgetClosing(widget);
  139. }
  140. void NativeWebContentsModalDialogManagerViews::OnWidgetDestroying(
  141. views::Widget* widget) {
  142. WidgetClosing(widget);
  143. }
  144. void NativeWebContentsModalDialogManagerViews::HostChanged(
  145. WebContentsModalDialogHost* new_host) {
  146. if (host_)
  147. host_->RemoveObserver(this);
  148. host_ = new_host;
  149. // |host_| may be null during WebContents destruction.
  150. if (host_) {
  151. host_->AddObserver(this);
  152. for (auto* widget : observed_widgets_) {
  153. views::Widget::ReparentNativeView(widget->GetNativeView(),
  154. host_->GetHostView());
  155. }
  156. OnPositionRequiresUpdate();
  157. }
  158. }
  159. gfx::NativeWindow NativeWebContentsModalDialogManagerViews::dialog() {
  160. return dialog_;
  161. }
  162. views::Widget* NativeWebContentsModalDialogManagerViews::GetWidget(
  163. gfx::NativeWindow dialog) {
  164. views::Widget* widget = views::Widget::GetWidgetForNativeWindow(dialog);
  165. DCHECK(widget);
  166. return widget;
  167. }
  168. void NativeWebContentsModalDialogManagerViews::WidgetClosing(
  169. views::Widget* widget) {
  170. #if defined(USE_AURA)
  171. gfx::NativeView view = widget->GetNativeView()->parent();
  172. // Allow the parent to animate again.
  173. if (view && view->parent())
  174. view->parent()->ClearProperty(aura::client::kAnimationsDisabledKey);
  175. #endif
  176. widget->RemoveObserver(this);
  177. observed_widgets_.erase(widget);
  178. #if defined(USE_AURA)
  179. shown_widgets_.erase(widget);
  180. #endif
  181. // Will cause this object to be deleted.
  182. native_delegate_->WillClose(widget->GetNativeWindow());
  183. }
  184. } // namespace constrained_window