overview_item.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. // Copyright 2013 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. #ifndef ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_
  5. #define ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/scoped_animation_disabler.h"
  9. #include "ash/wm/overview/overview_session.h"
  10. #include "ash/wm/overview/scoped_overview_transform_window.h"
  11. #include "ash/wm/window_state_observer.h"
  12. #include "base/gtest_prod_util.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "third_party/abseil-cpp/absl/types/optional.h"
  15. #include "ui/aura/scoped_window_event_targeting_blocker.h"
  16. #include "ui/aura/window.h"
  17. #include "ui/aura/window_observer.h"
  18. #include "ui/gfx/geometry/rect.h"
  19. #include "ui/gfx/geometry/rect_f.h"
  20. #include "ui/views/controls/button/button.h"
  21. namespace views {
  22. class Widget;
  23. } // namespace views
  24. namespace ash {
  25. class DragWindowController;
  26. class OverviewGrid;
  27. class OverviewItemView;
  28. class RoundedLabelWidget;
  29. class SystemShadow;
  30. // This class represents an item in overview mode.
  31. class ASH_EXPORT OverviewItem : public aura::WindowObserver,
  32. public WindowStateObserver {
  33. public:
  34. OverviewItem(aura::Window* window,
  35. OverviewSession* overview,
  36. OverviewGrid* overview_grid);
  37. OverviewItem(const OverviewItem&) = delete;
  38. OverviewItem& operator=(const OverviewItem&) = delete;
  39. ~OverviewItem() override;
  40. aura::Window* GetWindow();
  41. // Returns true if |target| is contained in this OverviewItem.
  42. bool Contains(const aura::Window* target) const;
  43. // This called when the window is dragged and dropped on the mini view of
  44. // another desk, which prepares this item for being removed from the grid, and
  45. // the window to restore its transform.
  46. void OnMovingWindowToAnotherDesk();
  47. // Restores and animates the managed window to its non overview mode state.
  48. // Doesn't animate if |was_desks_templates_grid_showing| is true. If
  49. // |reset_transform| equals false, the window's transform will not be reset to
  50. // identity transform when exiting overview mode. It's needed when dragging an
  51. // Arc app window in overview mode to put it in split screen. In this case the
  52. // restore of its transform needs to be deferred until the Arc app window is
  53. // snapped successfully, otherwise the animation will look very ugly (the Arc
  54. // app window enlarges itself to maximized window bounds and then shrinks to
  55. // its snapped window bounds). Note if the window's transform is not reset
  56. // here, it must be reset by someone else at some point.
  57. void RestoreWindow(bool reset_transform,
  58. bool was_desks_templates_grid_showing = false);
  59. // Ensures that a possibly minimized window becomes visible after restore.
  60. void EnsureVisible();
  61. // Restores stacking of window captions above the windows, then fades out.
  62. void Shutdown();
  63. // Hides the overview item. This is used to hide any overview items that may
  64. // be present when entering the desk templates UI. Animates `item_widget_` and
  65. // the windows in the transient tree to 0 opacity if `animate` is true,
  66. // otherwise just sets them to 0 opacity.
  67. void HideForDesksTemplatesGrid(bool animate);
  68. // This shows overview items that were hidden by the desk templates grid.
  69. // Called when exiting the desk templates UI and going back to the overview
  70. // grid. Fades the overview items in if `animate` is true, otherwise shows
  71. // them immediately.
  72. void RevertHideForDesksTemplatesGrid(bool animate);
  73. // Dispatched before beginning window overview. This will do any necessary
  74. // one time actions such as restoring minimized windows.
  75. void PrepareForOverview();
  76. // Calculates and returns an optimal scale ratio. With MD this is only
  77. // taking into account |size.height()| as the width can vary. Without MD this
  78. // returns the scale that allows the item to fully fit within |size|.
  79. float GetItemScale(const gfx::Size& size);
  80. // Returns the union of the original target bounds of all transformed windows
  81. // managed by |this| item, i.e. all regular (normal or panel transient
  82. // descendants of the window returned by GetWindow()).
  83. gfx::RectF GetTargetBoundsInScreen() const;
  84. // Returns the transformed bound of |transform_window_|.
  85. gfx::RectF GetTransformedBounds() const;
  86. // Sets the bounds of this overview item to |target_bounds| in the
  87. // |root_window_| root window. The bounds change will be animated as specified
  88. // by |animation_type|.
  89. void SetBounds(const gfx::RectF& target_bounds,
  90. OverviewAnimationType animation_type);
  91. // Sends an accessibility event indicating that this window became selected
  92. // so that it is highlighted and announced.
  93. void SendAccessibleSelectionEvent();
  94. // Slides the item up or down and then closes the associated window. Used by
  95. // overview swipe to close.
  96. void AnimateAndCloseWindow(bool up);
  97. // Closes |transform_window_|.
  98. void CloseWindow();
  99. // Shows the cannot snap warning if currently in splitview, and the associated
  100. // window cannot be snapped.
  101. void UpdateCannotSnapWarningVisibility(bool animate);
  102. // Hides the cannot snap warning (if it was showing) until the next call to
  103. // |UpdateCannotSnapWarningVisibility|.
  104. void HideCannotSnapWarning(bool animate);
  105. // Called when a OverviewItem on any grid is dragged. Hides the close button
  106. // when a drag is started, and reshows it when a drag is finished.
  107. // Additionally hides the title and window icon if |item| is this.
  108. void OnSelectorItemDragStarted(OverviewItem* item);
  109. void OnSelectorItemDragEnded(bool snap);
  110. // Shows/Hides window item during window dragging. Used when swiping up a
  111. // window from shelf.
  112. void SetVisibleDuringWindowDragging(bool visible, bool animate);
  113. OverviewGridWindowFillMode GetWindowDimensionsType() const;
  114. // Recalculates the window dimensions type of |transform_window_|. Called when
  115. // |window_|'s bounds change.
  116. void UpdateWindowDimensionsType();
  117. // TODO(minch): Do not actually scale up the item to get the bounds.
  118. // http://crbug.com/876567.
  119. // Returns the bounds of the selected item, which will be scaled up a little
  120. // bit and header view will be hidden after being selected. Note, the item
  121. // will be restored back after scaled up.
  122. gfx::Rect GetBoundsOfSelectedItem();
  123. // Increases the bounds of the dragged item.
  124. void ScaleUpSelectedItem(OverviewAnimationType animation_type);
  125. // If the window item represents a minimized window, update its content view.
  126. void UpdateItemContentViewForMinimizedWindow();
  127. // Checks if this item is currently being dragged.
  128. bool IsDragItem();
  129. // Inserts the window back to its original stacking order so that the order of
  130. // windows is the same as when entering overview.
  131. void Restack();
  132. // Updates |phantoms_for_dragging_|. If |phantoms_for_dragging_| is null, then
  133. // a new object is created for it.
  134. void UpdatePhantomsForDragging(bool is_touch_dragging);
  135. void DestroyPhantomsForDragging();
  136. // Sets the bounds of the window shadow. If |bounds_in_screen| is nullopt,
  137. // the shadow is hidden.
  138. void SetShadowBounds(absl::optional<gfx::RectF> bounds_in_screen);
  139. // Updates the rounded corners and shadow on this overview window item.
  140. void UpdateRoundedCornersAndShadow();
  141. // Updates the shadow type while being dragged and dropped.
  142. void UpdateShadowTypeForDrag(bool is_dragging);
  143. // Called when the starting animation is completed, or called immediately
  144. // if there was no starting animation.
  145. void OnStartingAnimationComplete();
  146. // Stops the current animation of |item_widget_|.
  147. void StopWidgetAnimation();
  148. // Changes the opacity of all the windows the item owns.
  149. void SetOpacity(float opacity);
  150. float GetOpacity();
  151. OverviewAnimationType GetExitOverviewAnimationType();
  152. OverviewAnimationType GetExitTransformAnimationType();
  153. // If kNewOverviewLayout is on, use this function for handling events.
  154. void HandleGestureEventForTabletModeLayout(ui::GestureEvent* event);
  155. // Handles events forwarded from |overview_item_view_|.
  156. void HandleMouseEvent(const ui::MouseEvent& event);
  157. void HandleGestureEvent(ui::GestureEvent* event);
  158. void OnHighlightedViewActivated();
  159. void OnHighlightedViewClosed();
  160. // aura::WindowObserver:
  161. void OnWindowPropertyChanged(aura::Window* window,
  162. const void* key,
  163. intptr_t old) override;
  164. void OnWindowBoundsChanged(aura::Window* window,
  165. const gfx::Rect& old_bounds,
  166. const gfx::Rect& new_bounds,
  167. ui::PropertyChangeReason reason) override;
  168. void OnWindowDestroying(aura::Window* window) override;
  169. // WindowStateObserver:
  170. void OnPreWindowStateTypeChange(WindowState* window_state,
  171. chromeos::WindowStateType old_type) override;
  172. void OnPostWindowStateTypeChange(WindowState* window_state,
  173. chromeos::WindowStateType old_type) override;
  174. // Returns the root window on which this item is shown.
  175. aura::Window* root_window() { return root_window_; }
  176. const gfx::RectF& target_bounds() const { return target_bounds_; }
  177. views::Widget* item_widget() { return item_widget_.get(); }
  178. OverviewItemView* overview_item_view() { return overview_item_view_; }
  179. OverviewGrid* overview_grid() { return overview_grid_; }
  180. bool is_moving_to_another_desk() const { return is_moving_to_another_desk_; }
  181. void set_should_use_spawn_animation(bool value) {
  182. should_use_spawn_animation_ = value;
  183. }
  184. bool should_use_spawn_animation() const {
  185. return should_use_spawn_animation_;
  186. }
  187. void set_should_animate_when_entering(bool should_animate) {
  188. should_animate_when_entering_ = should_animate;
  189. }
  190. bool should_animate_when_entering() const {
  191. return should_animate_when_entering_;
  192. }
  193. void set_should_animate_when_exiting(bool should_animate) {
  194. should_animate_when_exiting_ = should_animate;
  195. }
  196. bool should_animate_when_exiting() const {
  197. return should_animate_when_exiting_;
  198. }
  199. void set_should_restack_on_animation_end(bool val) {
  200. should_restack_on_animation_end_ = val;
  201. }
  202. void set_animating_to_close(bool val) { animating_to_close_ = val; }
  203. bool animating_to_close() const { return animating_to_close_; }
  204. void set_disable_mask(bool disable) { disable_mask_ = disable; }
  205. void set_unclipped_size(absl::optional<gfx::Size> unclipped_size) {
  206. unclipped_size_ = unclipped_size;
  207. }
  208. void set_scrolling_bounds(absl::optional<gfx::RectF> scrolling_bounds) {
  209. scrolling_bounds_ = scrolling_bounds;
  210. }
  211. absl::optional<gfx::RectF> scrolling_bounds() const {
  212. return scrolling_bounds_;
  213. }
  214. gfx::Rect GetShadowBoundsForTesting();
  215. RoundedLabelWidget* cannot_snap_widget_for_testing() {
  216. return cannot_snap_widget_.get();
  217. }
  218. void set_target_bounds_for_testing(const gfx::RectF& target_bounds) {
  219. target_bounds_ = target_bounds;
  220. }
  221. private:
  222. friend class OverviewTestBase;
  223. FRIEND_TEST_ALL_PREFIXES(SplitViewOverviewSessionTest, Clipping);
  224. // Returns the target bounds of |window_|. Same as |target_bounds_|, with some
  225. // insets.
  226. gfx::RectF GetWindowTargetBoundsWithInsets() const;
  227. // The shadow should match the size of the transformed window or preview
  228. // window if unclipped.
  229. gfx::RectF GetUnclippedShadowBounds() const;
  230. // Functions to be called back when their associated animations complete.
  231. void OnWindowCloseAnimationCompleted();
  232. void OnItemSpawnedAnimationCompleted();
  233. void OnItemBoundsAnimationStarted();
  234. void OnItemBoundsAnimationEnded();
  235. // Performs the spawn-item-in-overview animation (which is a fade-in plus
  236. // scale-up animation), on the given |window|. |target_transform| is the final
  237. // transform that should be applied to |window| at the end of the animation.
  238. // |window| is either the real window associated with this item (from
  239. // GetWindow()), or the `item_widget_->GetNativeWindow()` if the associated
  240. // window is minimized.
  241. void PerformItemSpawnedAnimation(aura::Window* window,
  242. const gfx::Transform& target_transform);
  243. // Sets the bounds of this overview item to |target_bounds| in |root_window_|.
  244. // The bounds change will be animated as specified by |animation_type|.
  245. // |is_first_update| is true when we set this item's bounds for the first
  246. // time.
  247. void SetItemBounds(const gfx::RectF& target_bounds,
  248. OverviewAnimationType animation_type,
  249. bool is_first_update);
  250. // Creates |item_widget_|, which holds |overview_item_view_|.
  251. void CreateItemWidget();
  252. // Updates the |item_widget|'s bounds. Any change in bounds will be animated
  253. // from the current bounds to the new bounds as per the |animation_type|.
  254. void UpdateHeaderLayout(OverviewAnimationType animation_type);
  255. // Animates opacity of the |transform_window_| and its caption to |opacity|
  256. // using |animation_type|.
  257. void AnimateOpacity(float opacity, OverviewAnimationType animation_type);
  258. // Called before dragging. Scales up the window a little bit to indicate its
  259. // selection and stacks the window at the top of the Z order in order to keep
  260. // it visible while dragging around.
  261. void StartDrag();
  262. void CloseButtonPressed();
  263. // TODO(sammiequon): Current events go from OverviewItemView to
  264. // OverviewItem to OverviewSession to OverviewWindowDragController. We may be
  265. // able to shorten this pipeline.
  266. void HandlePressEvent(const gfx::PointF& location_in_screen,
  267. bool from_touch_gesture);
  268. void HandleReleaseEvent(const gfx::PointF& location_in_screen);
  269. void HandleDragEvent(const gfx::PointF& location_in_screen);
  270. void HandleLongPressEvent(const gfx::PointF& location_in_screen);
  271. void HandleFlingStartEvent(const gfx::PointF& location_in_screen,
  272. float velocity_x,
  273. float velocity_y);
  274. void HandleTapEvent();
  275. void HandleGestureEndEvent();
  276. // Returns the list of windows that we want to slide up or down when swiping
  277. // on the shelf in tablet mode.
  278. aura::Window::Windows GetWindowsForHomeGesture();
  279. // The root window this item is being displayed on.
  280. aura::Window* root_window_;
  281. // The contained Window's wrapper.
  282. ScopedOverviewTransformWindow transform_window_;
  283. // The target bounds this overview item is fit within. When in splitview,
  284. // |item_widget_| is fit within these bounds, but the window itself is
  285. // transformed to |unclipped_size_|, and then clipped.
  286. gfx::RectF target_bounds_;
  287. // True if running SetItemBounds. This prevents recursive calls resulting from
  288. // the bounds update when calling ::wm::RecreateWindowLayers to copy
  289. // a window layer for display on another monitor.
  290. bool in_bounds_update_ = false;
  291. // A widget stacked under the |transform_window_|. The widget has
  292. // |overview_item_view_| as its contents view. The widget is backed by a
  293. // NOT_DRAWN layer since most of its surface is transparent.
  294. std::unique_ptr<views::Widget> item_widget_;
  295. // The view associated with |item_widget_|. Contains a title, close button and
  296. // maybe a backdrop. Forwards certain events to |this|.
  297. OverviewItemView* overview_item_view_ = nullptr;
  298. // A widget with text that may show up on top of |transform_window_| to notify
  299. // users this window cannot be snapped.
  300. std::unique_ptr<RoundedLabelWidget> cannot_snap_widget_;
  301. // Responsible for phantoms that look like the window on all displays during
  302. // dragging.
  303. std::unique_ptr<DragWindowController> phantoms_for_dragging_;
  304. // Pointer to the Overview that owns the OverviewGrid containing |this|.
  305. // Guaranteed to be non-null for the lifetime of |this|.
  306. OverviewSession* overview_session_;
  307. // Pointer to the OverviewGrid that contains |this|. Guaranteed to be non-null
  308. // for the lifetime of |this|.
  309. OverviewGrid* overview_grid_;
  310. // True when the item is dragged and dropped on another desk's mini view. This
  311. // causes it to restore its transform immediately without any animations,
  312. // since it is moving to an inactive desk, and therefore won't be visible.
  313. bool is_moving_to_another_desk_ = false;
  314. // True if this item should be added to an active overview session using the
  315. // spawn animation on its first update. This implies an animation type of
  316. // OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW. This value will be reset to
  317. // false once the spawn animation is performed.
  318. bool should_use_spawn_animation_ = false;
  319. // True if the contained window should animate during the entering animation.
  320. bool should_animate_when_entering_ = true;
  321. // True if the contained window should animate during the exiting animation.
  322. bool should_animate_when_exiting_ = true;
  323. // True if after an animation, we need to reorder the stacking order of the
  324. // widgets.
  325. bool should_restack_on_animation_end_ = false;
  326. // True if the windows are still alive so they can have a closing animation.
  327. // These windows should not be used in calculations for
  328. // OverviewGrid::PositionWindows.
  329. bool animating_to_close_ = false;
  330. // True if this overview item is currently being dragged around.
  331. bool is_being_dragged_ = false;
  332. // True to always disable mask regardless of the state.
  333. bool disable_mask_ = false;
  334. bool prepared_for_overview_ = false;
  335. // This has a value when there is a snapped window, or a window about to be
  336. // snapped (triggering a splitview preview area). This will be set when items
  337. // are positioned in OverviewGrid. The bounds delivered in |SetBounds| are the
  338. // true bounds of this item, but we want to maintain the aspect ratio of the
  339. // window, who's bounds are not set to split view size. So in |SetItemBounds|,
  340. // we transform the window not to |target_bounds_| but to this value, and then
  341. // apply clipping on the window to |target_bounds_|.
  342. absl::optional<gfx::Size> unclipped_size_ = absl::nullopt;
  343. // The shadow around the overview window. Shadows the original window, not
  344. // |item_widget_|. Done here instead of on the original window because of the
  345. // rounded edges mask applied on entering overview window.
  346. std::unique_ptr<SystemShadow> shadow_;
  347. // Cached values of the item bounds so that they do not have to be calculated
  348. // on each scroll update. Will be nullopt unless a grid scroll is underway.
  349. absl::optional<gfx::RectF> scrolling_bounds_ = absl::nullopt;
  350. // Used to block events from reaching the item widget when the overview item
  351. // has been hidden.
  352. std::unique_ptr<aura::ScopedWindowEventTargetingBlocker>
  353. item_widget_event_blocker_;
  354. // Disable animations on the contained window while it is being managed by the
  355. // overview item.
  356. ScopedAnimationDisabler animation_disabler_;
  357. base::WeakPtrFactory<OverviewItem> weak_ptr_factory_{this};
  358. };
  359. } // namespace ash
  360. #endif // ASH_WM_OVERVIEW_OVERVIEW_ITEM_H_