shelf.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. #ifndef ASH_SHELF_SHELF_H_
  5. #define ASH_SHELF_SHELF_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/public/cpp/metrics_util.h"
  9. #include "ash/public/cpp/shelf_types.h"
  10. #include "ash/shelf/shelf_layout_manager_observer.h"
  11. #include "ash/shelf/shelf_locking_manager.h"
  12. #include "base/observer_list.h"
  13. namespace aura {
  14. class Window;
  15. }
  16. namespace gfx {
  17. class Rect;
  18. }
  19. namespace ui {
  20. class GestureEvent;
  21. class MouseWheelEvent;
  22. class MouseEvent;
  23. class ScrollEvent;
  24. } // namespace ui
  25. namespace ash {
  26. enum class AnimationChangeType;
  27. class HotseatWidget;
  28. class HotseatWidgetAnimationMetricsReporter;
  29. class NavigationWidgetAnimationMetricsReporter;
  30. class ShelfFocusCycler;
  31. class LoginShelfWidget;
  32. class ShelfLayoutManager;
  33. class ShelfLayoutManagerTest;
  34. class ShelfLockingManager;
  35. class ShelfNavigationWidget;
  36. class ShelfView;
  37. class ShelfWidget;
  38. class StatusAreaWidget;
  39. class ShelfObserver;
  40. class WorkAreaInsets;
  41. class ShelfTooltipManager;
  42. // TODO(oshima) : move to .cc
  43. // Returns a value based on shelf alignment.
  44. template <typename T>
  45. T SelectValueByShelfAlignment(ShelfAlignment alignment,
  46. T bottom,
  47. T left,
  48. T right) {
  49. switch (alignment) {
  50. case ShelfAlignment::kBottom:
  51. case ShelfAlignment::kBottomLocked:
  52. return bottom;
  53. case ShelfAlignment::kLeft:
  54. return left;
  55. case ShelfAlignment::kRight:
  56. return right;
  57. }
  58. NOTREACHED();
  59. return bottom;
  60. }
  61. bool IsHorizontalAlignment(ShelfAlignment alignment);
  62. // Returns |horizontal| if shelf is horizontal, otherwise |vertical|.
  63. template <typename T>
  64. T PrimaryAxisValueByShelfAlignment(ShelfAlignment alignment,
  65. T horizontal,
  66. T vertical) {
  67. return IsHorizontalAlignment(alignment) ? horizontal : vertical;
  68. }
  69. // Controller for the shelf state. One per display, because each display might
  70. // have different shelf alignment, autohide, etc. Exists for the lifetime of the
  71. // root window controller.
  72. class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
  73. public:
  74. // Used to maintain a lock for the auto-hide shelf. If lock, then we should
  75. // not update the state of the auto-hide shelf.
  76. class ScopedAutoHideLock {
  77. public:
  78. explicit ScopedAutoHideLock(Shelf* shelf) : shelf_(shelf) {
  79. ++shelf_->auto_hide_lock_;
  80. }
  81. ~ScopedAutoHideLock() {
  82. --shelf_->auto_hide_lock_;
  83. DCHECK_GE(shelf_->auto_hide_lock_, 0);
  84. }
  85. private:
  86. Shelf* shelf_;
  87. };
  88. Shelf();
  89. Shelf(const Shelf&) = delete;
  90. Shelf& operator=(const Shelf&) = delete;
  91. ~Shelf() override;
  92. // Returns the shelf for the display that |window| is on. Note that the shelf
  93. // widget may not exist, or the shelf may not be visible.
  94. static Shelf* ForWindow(aura::Window* window);
  95. // Launch a 0-indexed shelf item in the shelf. A negative index launches the
  96. // last shelf item in the shelf.
  97. static void LaunchShelfItem(int item_index);
  98. // Activates the shelf item specified by the index in the list of shelf items.
  99. static void ActivateShelfItem(int item_index);
  100. // Activates the shelf item specified by the index in the list of shelf items
  101. // on the display identified by |display_id|.
  102. static void ActivateShelfItemOnDisplay(int item_index, int64_t display_id);
  103. // Updates the shelf visibility on all displays. This method exists for
  104. // historical reasons. If a display or shelf instance is available, prefer
  105. // Shelf::UpdateVisibilityState() below.
  106. static void UpdateShelfVisibility();
  107. void CreateNavigationWidget(aura::Window* container);
  108. void CreateHotseatWidget(aura::Window* container);
  109. void CreateStatusAreaWidget(aura::Window* status_container);
  110. void CreateShelfWidget(aura::Window* root);
  111. // Begins shutdown of the ShelfWidget and all child widgets.
  112. void ShutdownShelfWidget();
  113. // Resets `shelf_widget_`.
  114. void DestroyShelfWidget();
  115. // Returns true if the shelf is visible. Shelf can be visible in 1)
  116. // SHELF_VISIBLE or 2) SHELF_AUTO_HIDE but in SHELF_AUTO_HIDE_SHOWN. See
  117. // details in ShelfLayoutManager::IsVisible.
  118. bool IsVisible() const;
  119. // Returns the window showing the shelf.
  120. const aura::Window* GetWindow() const;
  121. aura::Window* GetWindow();
  122. void SetAlignment(ShelfAlignment alignment);
  123. // Returns true if the shelf alignment is horizontal (i.e. at the bottom).
  124. bool IsHorizontalAlignment() const;
  125. // Returns a value based on shelf alignment.
  126. template <typename T>
  127. T SelectValueForShelfAlignment(T bottom, T left, T right) const {
  128. return SelectValueByShelfAlignment(alignment_, bottom, left, right);
  129. }
  130. // Returns |horizontal| if shelf is horizontal, otherwise |vertical|.
  131. template <typename T>
  132. T PrimaryAxisValue(T horizontal, T vertical) const {
  133. return IsHorizontalAlignment() ? horizontal : vertical;
  134. }
  135. void SetAutoHideBehavior(ShelfAutoHideBehavior behavior);
  136. ShelfAutoHideState GetAutoHideState() const;
  137. // Invoke when the auto-hide state may have changed (for example, when the
  138. // system tray bubble opens it should force the shelf to be visible).
  139. void UpdateAutoHideState();
  140. ShelfBackgroundType GetBackgroundType() const;
  141. void UpdateVisibilityState();
  142. void MaybeUpdateShelfBackground();
  143. ShelfVisibilityState GetVisibilityState() const;
  144. gfx::Rect GetShelfBoundsInScreen() const;
  145. // Returns the ideal bounds of the shelf assuming it is visible.
  146. gfx::Rect GetIdealBounds() const;
  147. // Returns the ideal bounds of the shelf, but in tablet mode always returns
  148. // the bounds of the in-app shelf.
  149. gfx::Rect GetIdealBoundsForWorkAreaCalculation();
  150. // Returns the screen bounds of the item for the specified window. If there is
  151. // no item for the specified window an empty rect is returned.
  152. gfx::Rect GetScreenBoundsOfItemIconForWindow(aura::Window* window);
  153. // Handles a gesture |event| coming from a source outside the shelf widget
  154. // (e.g. the status area widget). Allows support for behaviors like toggling
  155. // auto-hide with a swipe, even if that gesture event hits another window.
  156. // Returns true if the event was handled.
  157. bool ProcessGestureEvent(const ui::GestureEvent& event);
  158. // Handles a mouse |event| coming from the Shelf.
  159. void ProcessMouseEvent(const ui::MouseEvent& event);
  160. // Handles a scroll |event| coming from the Shelf.
  161. void ProcessScrollEvent(ui::ScrollEvent* event);
  162. // Handles a mousewheel scroll event coming from the shelf.
  163. void ProcessMouseWheelEvent(ui::MouseWheelEvent* event);
  164. void AddObserver(ShelfObserver* observer);
  165. void RemoveObserver(ShelfObserver* observer);
  166. void NotifyShelfIconPositionsChanged();
  167. StatusAreaWidget* GetStatusAreaWidget() const;
  168. // Get the anchor rect that the system tray bubble and the notification center
  169. // bubble will be anchored.
  170. // x() and y() designates anchor point, but width() and height() are dummy.
  171. // See also: BubbleDialogDelegateView::GetBubbleBounds()
  172. gfx::Rect GetSystemTrayAnchorRect() const;
  173. // Returns whether this shelf should be hidden on secondary display in a given
  174. // |state|.
  175. bool ShouldHideOnSecondaryDisplay(session_manager::SessionState state);
  176. void SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds);
  177. ShelfLockingManager* GetShelfLockingManagerForTesting();
  178. ShelfView* GetShelfViewForTesting();
  179. ShelfLayoutManager* shelf_layout_manager() const {
  180. return shelf_layout_manager_;
  181. }
  182. // Getters for the various shelf components.
  183. ShelfWidget* shelf_widget() const { return shelf_widget_.get(); }
  184. ShelfNavigationWidget* navigation_widget() const {
  185. return navigation_widget_.get();
  186. }
  187. HotseatWidget* hotseat_widget() const { return hotseat_widget_.get(); }
  188. StatusAreaWidget* status_area_widget() const {
  189. return status_area_widget_.get();
  190. }
  191. LoginShelfWidget* login_shelf_widget() { return login_shelf_widget_.get(); }
  192. ShelfAlignment alignment() const { return alignment_; }
  193. ShelfAutoHideBehavior auto_hide_behavior() const {
  194. return auto_hide_behavior_;
  195. }
  196. ShelfAlignment stored_alignment() const {
  197. return shelf_locking_manager_.stored_alignment();
  198. }
  199. ShelfFocusCycler* shelf_focus_cycler() { return shelf_focus_cycler_.get(); }
  200. void set_is_tablet_mode_animation_running(bool value) {
  201. is_tablet_mode_animation_running_ = value;
  202. }
  203. bool is_tablet_mode_animation_running() const {
  204. return is_tablet_mode_animation_running_;
  205. }
  206. int auto_hide_lock() const { return auto_hide_lock_; }
  207. ShelfTooltipManager* tooltip() { return tooltip_.get(); }
  208. // |target_state| is the hotseat state after hotseat transition animation.
  209. metrics_util::ReportCallback GetHotseatTransitionReportCallback(
  210. HotseatState target_state);
  211. metrics_util::ReportCallback GetTranslucentBackgroundReportCallback(
  212. HotseatState target_state);
  213. metrics_util::ReportCallback GetNavigationWidgetAnimationReportCallback(
  214. HotseatState target_hotseat_state);
  215. protected:
  216. // ShelfLayoutManagerObserver:
  217. void WillDeleteShelfLayoutManager() override;
  218. void WillChangeVisibilityState(ShelfVisibilityState new_state) override;
  219. void OnAutoHideStateChanged(ShelfAutoHideState new_state) override;
  220. void OnBackgroundUpdated(ShelfBackgroundType background_type,
  221. AnimationChangeType change_type) override;
  222. void OnHotseatStateChanged(HotseatState old_state,
  223. HotseatState new_state) override;
  224. void OnWorkAreaInsetsChanged() override;
  225. private:
  226. class AutoDimEventHandler;
  227. class AutoHideEventHandler;
  228. friend class DimShelfLayoutManagerTestBase;
  229. friend class ShelfLayoutManagerTest;
  230. // Uses Auto Dim Event Handler to update the shelf dim state.
  231. void DimShelf();
  232. void UndimShelf();
  233. bool HasDimShelfTimer();
  234. // Returns work area insets object for the window with this shelf.
  235. WorkAreaInsets* GetWorkAreaInsets() const;
  236. // Layout manager for the shelf container window. Instances are constructed by
  237. // ShelfWidget and lifetimes are managed by the container windows themselves.
  238. ShelfLayoutManager* shelf_layout_manager_ = nullptr;
  239. // Pointers to shelf components.
  240. std::unique_ptr<ShelfNavigationWidget> navigation_widget_;
  241. std::unique_ptr<HotseatWidget> hotseat_widget_;
  242. std::unique_ptr<StatusAreaWidget> status_area_widget_;
  243. // Null during display teardown, see WindowTreeHostManager::DeleteHost() and
  244. // RootWindowController::CloseAllChildWindows().
  245. std::unique_ptr<ShelfWidget> shelf_widget_;
  246. std::unique_ptr<LoginShelfWidget> login_shelf_widget_;
  247. // These initial values hide the shelf until user preferences are available.
  248. ShelfAlignment alignment_ = ShelfAlignment::kBottomLocked;
  249. ShelfAutoHideBehavior auto_hide_behavior_ =
  250. ShelfAutoHideBehavior::kAlwaysHidden;
  251. // Sets shelf alignment to bottom during login and screen lock.
  252. ShelfLockingManager shelf_locking_manager_;
  253. base::ObserverList<ShelfObserver>::Unchecked observers_;
  254. // Forwards mouse and gesture events to ShelfLayoutManager for auto-hide.
  255. std::unique_ptr<AutoHideEventHandler> auto_hide_event_handler_;
  256. // Forwards mouse and gesture events to ShelfLayoutManager for auto-dim.
  257. std::unique_ptr<AutoDimEventHandler> auto_dim_event_handler_;
  258. // Hands focus off to different parts of the shelf.
  259. std::unique_ptr<ShelfFocusCycler> shelf_focus_cycler_;
  260. // Animation metrics reporter for hotseat animations. Owned by the Shelf to
  261. // ensure it outlives the Hotseat Widget.
  262. std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
  263. hotseat_transition_metrics_reporter_;
  264. // Metrics reporter for animations of the traslucent background in the
  265. // hotseat. Owned by the Shelf to ensure it outlives the Hotseat Widget.
  266. std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
  267. translucent_background_metrics_reporter_;
  268. // Animation metrics reporter for navigation widget animations. Owned by the
  269. // Shelf to ensure it outlives the Navigation Widget.
  270. std::unique_ptr<NavigationWidgetAnimationMetricsReporter>
  271. navigation_widget_metrics_reporter_;
  272. // True while the animation to enter or exit tablet mode is running. Sometimes
  273. // this value is true when the shelf movements are not actually animating
  274. // (animation value = 0.0). This is because this is set to true when we
  275. // enter/exit tablet mode but the animation is not started until a shelf
  276. // OnBoundsChanged is called because of tablet mode. Use this value to sync
  277. // the animation for HomeButton.
  278. bool is_tablet_mode_animation_running_ = false;
  279. // Used by ScopedAutoHideLock to maintain the state of the lock for auto-hide
  280. // shelf.
  281. int auto_hide_lock_ = 0;
  282. std::unique_ptr<ShelfTooltipManager> tooltip_;
  283. };
  284. } // namespace ash
  285. #endif // ASH_SHELF_SHELF_H_