window_cycle_view.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. // Copyright 2021 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_WINDOW_CYCLE_WINDOW_CYCLE_VIEW_H_
  5. #define ASH_WM_WINDOW_CYCLE_WINDOW_CYCLE_VIEW_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/wm/gestures/wm_fling_handler.h"
  9. #include "ash/wm/window_cycle/window_cycle_tab_slider.h"
  10. #include "base/containers/flat_set.h"
  11. #include "ui/aura/window_occlusion_tracker.h"
  12. #include "ui/base/metadata/metadata_header_macros.h"
  13. #include "ui/compositor/layer_animation_observer.h"
  14. #include "ui/gfx/geometry/rect.h"
  15. #include "ui/views/widget/widget_delegate.h"
  16. namespace aura {
  17. class Window;
  18. }
  19. namespace views {
  20. class Label;
  21. }
  22. namespace ash {
  23. class WindowCycleItemView;
  24. // A view that shows a collection of windows the user can cycle through.
  25. class ASH_EXPORT WindowCycleView : public views::WidgetDelegateView,
  26. public ui::ImplicitAnimationObserver {
  27. public:
  28. METADATA_HEADER(WindowCycleView);
  29. using WindowList = std::vector<aura::Window*>;
  30. // Horizontal padding between the alt-tab bandshield and the window
  31. // previews.
  32. static constexpr int kInsideBorderHorizontalPaddingDp = 64;
  33. WindowCycleView(aura::Window* root_window, const WindowList& windows);
  34. WindowCycleView(const WindowCycleView&) = delete;
  35. WindowCycleView& operator=(const WindowCycleView&) = delete;
  36. ~WindowCycleView() override;
  37. aura::Window* target_window() const { return target_window_; }
  38. // Scales the window cycle view by scaling its clip rect. If the widget is
  39. // growing, the widget's bounds are set to `screen_bounds` immediately then
  40. // its clipping rect is scaled. If the widget is shrinking, the widget's
  41. // cliping rect is scaled first then the widget's bounds are set to
  42. // |screen_bounds| upon completion/interruption of the clipping rect's
  43. // animation.
  44. void ScaleCycleView(const gfx::Rect& screen_bounds);
  45. // Returns the target bounds of |this|, that is its preferred size clamped to
  46. // the root window's bounds.
  47. gfx::Rect GetTargetBounds() const;
  48. // Recreates the `WindowCycleView` with the provided `windows`.
  49. void UpdateWindows(const WindowList& windows);
  50. // Fades the `WindowCycleView` in.
  51. void FadeInLayer();
  52. // Scrolls the `WindowCycleView` to `target`.
  53. void ScrollToWindow(aura::Window* target);
  54. // Makes `target` the new `target_window_`, moving the focus ring to its
  55. // respective `WindowCycleItemView`.
  56. void SetTargetWindow(aura::Window* target);
  57. // Removes the `destroying_window`'s respective `WindowCycleItemView` and sets
  58. // `new_target` as the new `target_window_`.
  59. void HandleWindowDestruction(aura::Window* destroying_window,
  60. aura::Window* new_target);
  61. // Clears all state and removes all child views.
  62. void DestroyContents();
  63. // Horizontally translates the `WindowCycleView` by `delta_x`.
  64. void Drag(float delta_x);
  65. // Creates a `WmFlingHandler` which will horizontally translate the
  66. // `WindowCycleView`.
  67. void StartFling(float velocity_x);
  68. // Called on each fling step, updates `horizontal_distance_dragged_` by
  69. // `offset`.
  70. bool OnFlingStep(float offset);
  71. // Called when a fling ends, cleans up fling state.
  72. void OnFlingEnd();
  73. // Sets whether the `tab_slider_container_` is focused.
  74. void SetFocusTabSlider(bool focus);
  75. // Returns whether the `tab_slider_container_` is focused.
  76. bool IsTabSliderFocused();
  77. // Returns the corresponding window for the `WindowCycleItemView` located at
  78. // `screen_point`.
  79. aura::Window* GetWindowAtPoint(const gfx::Point& screen_point);
  80. // Called when the alt-tab mode is changed, notifying the
  81. // `tab_slider_container_` of the change.
  82. void OnModePrefsChanged();
  83. // views::WidgetDelegateView:
  84. gfx::Size CalculatePreferredSize() const override;
  85. void Layout() override;
  86. void OnThemeChanged() override;
  87. // ui::ImplicitAnimationObserver:
  88. void OnImplicitAnimationsCompleted() override;
  89. // Returns whether or not the given `screen_point` is located in tab slider
  90. // container.
  91. bool IsEventInTabSliderContainer(const gfx::Point& screen_point);
  92. // Returns the maximum width of the cycle view.
  93. int CalculateMaxWidth() const;
  94. private:
  95. friend class WindowCycleListTestApi;
  96. // Returns a bound of alt-tab content container, which represents the mirror
  97. // container when there is at least one window and represents no-recent-items
  98. // label when there is no window to be shown.
  99. gfx::Rect GetContentContainerBounds() const;
  100. // The root window that `this` resides on.
  101. aura::Window* const root_window_;
  102. // A mapping from a window to its respective `WindowCycleItemView`.
  103. std::map<aura::Window*, WindowCycleItemView*> window_view_map_;
  104. // A container that houses and lays out all the `WindowCycleItemView`s.
  105. views::View* mirror_container_ = nullptr;
  106. // Tab slider and no recent items are only used when Bento is enabled.
  107. WindowCycleTabSlider* tab_slider_container_ = nullptr;
  108. views::Label* no_recent_items_label_ = nullptr;
  109. // The |target_window_| is the window that has the focus ring. When the user
  110. // completes cycling the |target_window_| is activated.
  111. aura::Window* target_window_ = nullptr;
  112. // The |current_window_| is the window that the window cycle list uses to
  113. // determine the layout and positioning of the list's items. If this window's
  114. // preview can equally divide the list it is centered, otherwise it is
  115. // off-center.
  116. aura::Window* current_window_ = nullptr;
  117. // Used when the widget bounds update should be deferred during the cycle
  118. // view's scaling animation..
  119. bool defer_widget_bounds_update_ = false;
  120. // Set which contains items which have been created but have some of their
  121. // performance heavy elements not created yet. These elements will be created
  122. // once onscreen to improve fade in performance, then removed from this set.
  123. base::flat_set<WindowCycleItemView*> no_previews_set_;
  124. // Used for preventng occlusion state computations for the duration of the
  125. // fade in animation.
  126. std::unique_ptr<aura::WindowOcclusionTracker::ScopedPause>
  127. occlusion_tracker_pauser_;
  128. // Tracks the distance that a user has dragged, offsetting the
  129. // |mirror_container_|. This should be reset only when a user cycles the
  130. // window cycle list or when the user switches alt-tab modes.
  131. float horizontal_distance_dragged_ = 0.f;
  132. // Fling handler of the current active fling. Nullptr while a fling is not
  133. // active.
  134. std::unique_ptr<WmFlingHandler> fling_handler_;
  135. // True once `DestroyContents` is called. Used to prevent `Layout` from being
  136. // called once all the child views have been removed. See
  137. // https://crbug.com/1223302 for more details.
  138. bool is_destroying_ = false;
  139. };
  140. } // namespace ash
  141. #endif // ASH_WM_WINDOW_CYCLE_WINDOW_CYCLE_VIEW_H_