overview_session.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  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_SESSION_H_
  5. #define ASH_WM_OVERVIEW_OVERVIEW_SESSION_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <memory>
  9. #include <vector>
  10. #include "ash/ash_export.h"
  11. #include "ash/public/cpp/shelf_types.h"
  12. #include "ash/public/cpp/tablet_mode_observer.h"
  13. #include "ash/shell_observer.h"
  14. #include "ash/wm/desks/desks_controller.h"
  15. #include "ash/wm/overview/overview_types.h"
  16. #include "ash/wm/overview/scoped_overview_hide_windows.h"
  17. #include "ash/wm/splitview/split_view_controller.h"
  18. #include "ash/wm/splitview/split_view_drag_indicators.h"
  19. #include "ash/wm/splitview/split_view_observer.h"
  20. #include "base/containers/flat_set.h"
  21. #include "base/guid.h"
  22. #include "base/scoped_observation.h"
  23. #include "base/time/time.h"
  24. #include "ui/aura/window_observer.h"
  25. #include "ui/display/display_observer.h"
  26. #include "ui/events/event_handler.h"
  27. #include "ui/wm/public/activation_change_observer.h"
  28. namespace gfx {
  29. class PointF;
  30. } // namespace gfx
  31. namespace ui {
  32. class KeyEvent;
  33. } // namespace ui
  34. namespace views {
  35. class Widget;
  36. } // namespace views
  37. namespace ash {
  38. class OverviewDelegate;
  39. class OverviewGrid;
  40. class OverviewHighlightController;
  41. class OverviewItem;
  42. class OverviewWindowDragController;
  43. class SavedDeskDialogController;
  44. class SavedDeskPresenter;
  45. // The Overview shows a grid of all of your windows, allowing to select
  46. // one by clicking or tapping on it.
  47. class ASH_EXPORT OverviewSession : public display::DisplayObserver,
  48. public aura::WindowObserver,
  49. public ui::EventHandler,
  50. public ShellObserver,
  51. public SplitViewObserver,
  52. public TabletModeObserver,
  53. public DesksController::Observer {
  54. public:
  55. using WindowList = std::vector<aura::Window*>;
  56. explicit OverviewSession(OverviewDelegate* delegate);
  57. OverviewSession(const OverviewSession&) = delete;
  58. OverviewSession& operator=(const OverviewSession&) = delete;
  59. ~OverviewSession() override;
  60. // Initialize with the windows that can be selected.
  61. void Init(const WindowList& windows, const WindowList& hide_windows);
  62. // Perform cleanup that cannot be done in the destructor.
  63. void Shutdown();
  64. // Called when the last overview item from a grid is deleted.
  65. void OnGridEmpty();
  66. // Moves the current selection forwards or backwards.
  67. void IncrementSelection(bool forward);
  68. // Accepts current selection if any. Returns true if a selection was made,
  69. // false otherwise.
  70. bool AcceptSelection();
  71. // Activates |item's| window.
  72. void SelectWindow(OverviewItem* item);
  73. // Sets the dragged window on the split view drag indicators.
  74. void SetSplitViewDragIndicatorsDraggedWindow(aura::Window* dragged_window);
  75. // If |state_on_root_window_being_dragged_in| is kNoDrag, this function sets
  76. // the state on every root window to kNoDrag. Otherwise it sets the state on
  77. // |root_window_being_dragged_in| to |state_on_root_window_being_dragged_in|,
  78. // and sets the state on other root windows to kOtherDisplay.
  79. void UpdateSplitViewDragIndicatorsWindowDraggingStates(
  80. const aura::Window* root_window_being_dragged_in,
  81. SplitViewDragIndicators::WindowDraggingState
  82. state_on_root_window_being_dragged_in);
  83. // Sets the state on every root window to kNoDrag.
  84. void ResetSplitViewDragIndicatorsWindowDraggingStates();
  85. // See |OverviewGrid::RearrangeDuringDrag|.
  86. void RearrangeDuringDrag(OverviewItem* dragged_item);
  87. // Updates the appearance of each drop target to visually indicate when the
  88. // dragged window is being dragged over it.
  89. void UpdateDropTargetsBackgroundVisibilities(
  90. OverviewItem* dragged_item,
  91. const gfx::PointF& location_in_screen);
  92. // Retrieves the window grid whose root window matches |root_window|. Returns
  93. // nullptr if the window grid is not found.
  94. OverviewGrid* GetGridWithRootWindow(aura::Window* root_window);
  95. // Adds |window| at the specified |index| into the grid with the same root
  96. // window. Does nothing if that grid does not exist in |grid_list_| or already
  97. // contains |window|. If |reposition| is true, repositions all items in the
  98. // target grid (unless it already contained |window|), except those in
  99. // |ignored_items|. If |animate| is true, animates the repositioning.
  100. // |animate| has no effect if |reposition| is false.
  101. void AddItem(aura::Window* window,
  102. bool reposition,
  103. bool animate,
  104. const base::flat_set<OverviewItem*>& ignored_items,
  105. size_t index);
  106. // Similar to the above function, but adds the window at the end of the grid.
  107. // This will use the spawn-item animation.
  108. // TODO(afakhry): Expose |use_spawn_animation| if needed.
  109. void AppendItem(aura::Window* window, bool reposition, bool animate);
  110. // Like |AddItem|, but adds |window| at the correct position according to MRU
  111. // order. If |reposition|, |animate|, and |restack| are all true, the stacking
  112. // order will be adjusted after the animation. If |restack| is true but at
  113. // least one of |reposition| and |animate| is false, the stacking order will
  114. // be adjusted immediately.
  115. void AddItemInMruOrder(aura::Window* window,
  116. bool reposition,
  117. bool animate,
  118. bool restack,
  119. bool use_spawn_animation);
  120. // Removes |overview_item| from the corresponding grid.
  121. void RemoveItem(OverviewItem* overview_item);
  122. void RemoveItem(OverviewItem* overview_item,
  123. bool item_destroying,
  124. bool reposition);
  125. void RemoveDropTargets();
  126. void InitiateDrag(OverviewItem* item,
  127. const gfx::PointF& location_in_screen,
  128. bool is_touch_dragging);
  129. void Drag(OverviewItem* item, const gfx::PointF& location_in_screen);
  130. void CompleteDrag(OverviewItem* item, const gfx::PointF& location_in_screen);
  131. void StartNormalDragMode(const gfx::PointF& location_in_screen);
  132. void Fling(OverviewItem* item,
  133. const gfx::PointF& location_in_screen,
  134. float velocity_x,
  135. float velocity_y);
  136. void ActivateDraggedWindow();
  137. void ResetDraggedWindowGesture();
  138. // Called when a window (either it's browser window or an app window)
  139. // start/continue/end being dragged in tablet mode by swiping from the top
  140. // of the screen to drag from top or by swiping from the shelf to drag from
  141. // bottom .
  142. // TODO(xdai): Currently it doesn't work for multi-display scenario.
  143. void OnWindowDragStarted(aura::Window* dragged_window, bool animate);
  144. void OnWindowDragContinued(
  145. aura::Window* dragged_window,
  146. const gfx::PointF& location_in_screen,
  147. SplitViewDragIndicators::WindowDraggingState window_dragging_state);
  148. void OnWindowDragEnded(aura::Window* dragged_window,
  149. const gfx::PointF& location_in_screen,
  150. bool should_drop_window_into_overview,
  151. bool snap);
  152. // Shows or Hides all windows (including drop target window & desk widget) in
  153. // overview. It's used when dragging a window from bottom, when the user slows
  154. // down or stops dragging the window, shows overview windows and when the user
  155. // resumes dragging, hides overview windows.
  156. void SetVisibleDuringWindowDragging(bool visible, bool animate);
  157. // This is called on drag end for WebUI Tab Strip similar to
  158. // OnWindowDragEnded. Since WebUI tab strip tab dragging only creates new
  159. // window on drag end, both OnWindowDragStarted and OnWindowDragContinued are
  160. // not being called.
  161. void MergeWindowIntoOverviewForWebUITabStrip(aura::Window* dragged_window);
  162. // Positions all overview items except those in |ignored_items|.
  163. void PositionWindows(bool animate,
  164. const base::flat_set<OverviewItem*>& ignored_items = {});
  165. // Returns true if |window| is currently showing in overview.
  166. bool IsWindowInOverview(const aura::Window* window);
  167. // Returns the overview item for |window|, or nullptr if |window| doesn't have
  168. // a corresponding item in overview mode.
  169. OverviewItem* GetOverviewItemForWindow(const aura::Window* window);
  170. // Set the window grid that's displaying in |root_window| not animate when
  171. // exiting overview mode, i.e., all window items in the grid will not animate
  172. // when exiting overview mode. It may be called in two cases: 1) When a window
  173. // gets snapped (either from overview or not) and thus cause the end of the
  174. // overview mode, we should not do the exiting animation; 2) When a window
  175. // is dragged around and when released, it causes the end of the overview
  176. // mode, we also should not do the exiting animation.
  177. void SetWindowListNotAnimatedWhenExiting(aura::Window* root_window);
  178. // Shifts and fades the grid in |grid_list_| associated with |location|.
  179. // Updates all the overview items' mask and shadow.
  180. void UpdateRoundedCornersAndShadow();
  181. // Called when the overview mode starting animation completes. |canceled| is
  182. // true when the starting animation is interrupted by ending overview mode. If
  183. // |canceled| is false and |should_focus_overview| is true, then
  184. // |overview_focus_widget_| shall gain focus. |should_focus_overview| has no
  185. // effect when |canceled| is true.
  186. void OnStartingAnimationComplete(bool canceled, bool should_focus_overview);
  187. // Called when windows are being activated/deactivated during
  188. // overview mode.
  189. void OnWindowActivating(
  190. ::wm::ActivationChangeObserver::ActivationReason reason,
  191. aura::Window* gained_active,
  192. aura::Window* lost_active);
  193. // Returns true when either the `DesksTemplatesGridWidget` or
  194. // `SavedDeskDialog` is the window that is losing activation.
  195. bool IsTemplatesUiLosingActivation(aura::Window* lost_active);
  196. // Gets the window which keeps focus for the duration of overview mode.
  197. aura::Window* GetOverviewFocusWindow();
  198. // Returns the window highlighted by the selector widget.
  199. aura::Window* GetHighlightedWindow();
  200. // Suspends/Resumes window re-positiong in overview.
  201. void SuspendReposition();
  202. void ResumeReposition();
  203. // Returns true if all its window grids don't have any window item.
  204. bool IsEmpty() const;
  205. // If |restore| is true, activate window |active_window_before_overview_|.
  206. // This is usually called when exiting overview to restore window activation
  207. // to the window that was active before entering overview. If |restore| is
  208. // false, reset |active_window_before_overview_| to nullptr so that window
  209. // activation will not be restore when overview is ended.
  210. void RestoreWindowActivation(bool restore);
  211. // Handles requests to active or close the currently highlighted |item|.
  212. void OnHighlightedItemActivated(OverviewItem* item);
  213. void OnHighlightedItemClosed(OverviewItem* item);
  214. // Called explicitly (with no list of observers) by the |RootWindowController|
  215. // of |root|, so that the associated grid is properly removed and destroyed.
  216. // Note: Usually, when a display is removed, it causes a window activation
  217. // which ends overview mode, and then this function does not get called. This
  218. // function is only needed for when overview mode cannot be ended (see
  219. // |OverviewController::CanEndOverview| and https://crbug.com/1024325).
  220. void OnRootWindowClosing(aura::Window* root);
  221. // Returns the current dragged overview item if any. Note that windows that
  222. // are dragged into overview from the shelf don't have an OverviewItem while
  223. // dragging.
  224. OverviewItem* GetCurrentDraggedOverviewItem() const;
  225. // Overview objects which handle events (OverviewItemView,
  226. // OverviewGridEventHandler) should call this function to check if they can
  227. // process an event. Returns false if an overview item other than |sender|
  228. // (which may be nullptr in the case of events on the wallpaper) is already
  229. // being dragged, or if a window is currently being dragged from the bottom.
  230. // This is so we can allow switching finger while dragging, but not allow
  231. // dragging two or more items. The first |CanProcessEvent()| calls the second
  232. // with |sender| as nullptr (i.e. event processed by
  233. // OverviewGridEventHandler). When |sender| is nullptr, |from_touch_gesture|
  234. // does not matter.
  235. bool CanProcessEvent() const;
  236. bool CanProcessEvent(OverviewItem* sender, bool from_touch_gesture) const;
  237. // Returns true if |window| is not nullptr and equals
  238. // |active_window_before_overview_|.
  239. bool IsWindowActiveWindowBeforeOverview(aura::Window* window) const;
  240. // Shows the desks templates grids on all displays. If `was_zero_state` is
  241. // true then we will expand the desks bars. Focuses the item which matches
  242. // `item_to_focus` on the display associated with `root_window`.
  243. void ShowDesksTemplatesGrids(bool was_zero_state,
  244. const base::GUID& item_to_focus,
  245. const std::u16string& saved_desk_name,
  246. aura::Window* const root_window);
  247. void HideDesksTemplatesGrids();
  248. bool IsShowingDesksTemplatesGrid() const;
  249. // Updates the focusable overview widgets so that they point to the correct
  250. // next and previous widgets for a11y purposes. Needs to be updated when a
  251. // piece of UI is shown or hidden.
  252. void UpdateAccessibilityFocus();
  253. // DesksController::Observer:
  254. void OnDeskAdded(const Desk* desk) override;
  255. void OnDeskRemoved(const Desk* desk) override;
  256. void OnDeskReordered(int old_index, int new_index) override;
  257. void OnDeskActivationChanged(const Desk* activated,
  258. const Desk* deactivated) override;
  259. void OnDeskSwitchAnimationLaunching() override;
  260. void OnDeskSwitchAnimationFinished() override;
  261. void OnDeskNameChanged(const Desk* desk,
  262. const std::u16string& new_name) override;
  263. // display::DisplayObserver:
  264. void OnDisplayAdded(const display::Display& display) override;
  265. void OnDisplayMetricsChanged(const display::Display& display,
  266. uint32_t metrics) override;
  267. // aura::WindowObserver:
  268. void OnWindowDestroying(aura::Window* window) override;
  269. void OnWindowAdded(aura::Window* new_window) override;
  270. // ui::EventHandler:
  271. void OnKeyEvent(ui::KeyEvent* event) override;
  272. // ShellObserver:
  273. void OnShellDestroying() override;
  274. void OnShelfAlignmentChanged(aura::Window* root_window,
  275. ShelfAlignment old_alignment) override;
  276. void OnUserWorkAreaInsetsChanged(aura::Window* root_window) override;
  277. // SplitViewObserver:
  278. void OnSplitViewStateChanged(SplitViewController::State previous_state,
  279. SplitViewController::State state) override;
  280. void OnSplitViewDividerPositionChanged() override;
  281. // TabletModeObserver:
  282. void OnTabletModeStarted() override;
  283. void OnTabletModeEnded() override;
  284. void UpdateFrameThrottling();
  285. OverviewDelegate* delegate() { return delegate_; }
  286. bool is_shutting_down() const { return is_shutting_down_; }
  287. void set_is_shutting_down(bool is_shutting_down) {
  288. is_shutting_down_ = is_shutting_down;
  289. }
  290. const std::vector<std::unique_ptr<OverviewGrid>>& grid_list() const {
  291. return grid_list_;
  292. }
  293. size_t num_items() const { return num_items_; }
  294. OverviewEnterExitType enter_exit_overview_type() const {
  295. return enter_exit_overview_type_;
  296. }
  297. void set_enter_exit_overview_type(OverviewEnterExitType val) {
  298. enter_exit_overview_type_ = val;
  299. }
  300. OverviewWindowDragController* window_drag_controller() {
  301. return window_drag_controller_.get();
  302. }
  303. OverviewHighlightController* highlight_controller() {
  304. return highlight_controller_.get();
  305. }
  306. SavedDeskPresenter* saved_desk_presenter() {
  307. return saved_desk_presenter_.get();
  308. }
  309. SavedDeskDialogController* saved_desk_dialog_controller() {
  310. return saved_desk_dialog_controller_.get();
  311. }
  312. void set_auto_add_windows_enabled(bool enabled) {
  313. auto_add_windows_enabled_ = enabled;
  314. }
  315. void set_allow_empty_desk_without_exiting(bool enabled) {
  316. allow_empty_desk_without_exiting_ = enabled;
  317. }
  318. private:
  319. friend class DesksAcceleratorsTest;
  320. friend class OverviewTestBase;
  321. // Called when tablet mode changes.
  322. void OnTabletModeChanged();
  323. // Helper function that moves the highlight forward or backward on the
  324. // corresponding window grid.
  325. void Move(bool reverse);
  326. // Helper function that processes a key event and maybe scrolls the overview
  327. // grid on the primary display.
  328. bool ProcessForScrolling(const ui::KeyEvent& event);
  329. // Removes all observers that were registered during construction and/or
  330. // initialization.
  331. void RemoveAllObservers();
  332. // Updates the no windows widget on each OverviewGrid.
  333. void UpdateNoWindowsWidgetOnEachGrid();
  334. // Refreshes the bounds of the no windows widget on each OverviewGrid.
  335. void RefreshNoWindowsWidgetBoundsOnEachGrid(bool animate);
  336. void OnItemAdded(aura::Window* window);
  337. // Called when a window is activated or deactivated and the saved desk feature
  338. // is enabled. Returns true if we should keep overview open. Overview should
  339. // be kept open if `gained_active` or `lost_active` is a saved desk dialog.
  340. bool ShouldKeepOverviewOpenForSavedDeskDialog(aura::Window* gained_active,
  341. aura::Window* lost_active);
  342. // Weak pointer to the overview delegate which will be called when a selection
  343. // is made.
  344. OverviewDelegate* delegate_;
  345. // A weak pointer to the window which was active on starting overview. If
  346. // overview is canceled the activation should be restored to this window.
  347. aura::Window* active_window_before_overview_ = nullptr;
  348. // A hidden window that receives focus while in overview mode. It is needed
  349. // because accessibility needs something focused for it to work and we cannot
  350. // use one of the overview windows otherwise wm::ActivateWindow will not
  351. // work.
  352. // TODO(sammiequon): Focus the grid desks widget if it is always available, or
  353. // we may be able to add some mechanism to trigger accessibility events
  354. // without a focused window.
  355. std::unique_ptr<views::Widget> overview_focus_widget_;
  356. // True when performing operations that may cause window activations. This is
  357. // used to prevent handling the resulting expected activation. This is
  358. // initially true until this is initialized.
  359. bool ignore_activations_ = true;
  360. // True when overview mode is exiting.
  361. bool is_shutting_down_ = false;
  362. // List of all the window overview grids, one for each root window.
  363. std::vector<std::unique_ptr<OverviewGrid>> grid_list_;
  364. // The following variables are used for metric collection purposes. All of
  365. // them refer to this particular overview session and are not cumulative:
  366. // The time when overview was started.
  367. base::Time overview_start_time_;
  368. // The number of arrow key presses.
  369. size_t num_key_presses_ = 0;
  370. // The number of items in the overview.
  371. size_t num_items_ = 0;
  372. // True if we are currently using keyboard (control + left/right) to scroll
  373. // through the grid.
  374. bool is_keyboard_scrolling_grid_ = false;
  375. // Stores the overview enter/exit type. See the enum declaration for
  376. // information on how these types affect overview mode.
  377. OverviewEnterExitType enter_exit_overview_type_ =
  378. OverviewEnterExitType::kNormal;
  379. // The selected item when exiting overview mode. nullptr if no window
  380. // selected.
  381. OverviewItem* selected_item_ = nullptr;
  382. // The drag controller for a window in the overview mode.
  383. std::unique_ptr<OverviewWindowDragController> window_drag_controller_;
  384. std::unique_ptr<ScopedOverviewHideWindows> hide_overview_windows_;
  385. std::unique_ptr<OverviewHighlightController> highlight_controller_;
  386. // The object responsible to talking to the desk model.
  387. std::unique_ptr<SavedDeskPresenter> saved_desk_presenter_;
  388. // Controls showing and hiding dialogs associated with the saved desks
  389. // feature.
  390. std::unique_ptr<SavedDeskDialogController> saved_desk_dialog_controller_;
  391. absl::optional<display::ScopedDisplayObserver> display_observer_;
  392. // Boolean to indicate whether chromeVox is enabled or not.
  393. bool chromevox_enabled_;
  394. // When non-null, windows changes on this desk are observed.
  395. const Desk* observing_desk_ = nullptr;
  396. // This is true *while* an overview item is being dynamically added. It is
  397. // used to avoid recursively adding overview items.
  398. bool is_adding_new_item_ = false;
  399. // When true, windows added to the observed desk are automatically added to
  400. // the overview session.
  401. bool auto_add_windows_enabled_ = true;
  402. // When true, the overview session is not exited when the last window is
  403. // removed.
  404. bool allow_empty_desk_without_exiting_ = false;
  405. base::ScopedObservation<TabletModeController, TabletModeObserver>
  406. tablet_mode_observation_{this};
  407. base::ScopedObservation<DesksController, DesksController::Observer>
  408. desks_controller_observation_{this};
  409. base::ScopedObservation<aura::Window, aura::WindowObserver>
  410. active_window_before_overview_observation_{this};
  411. };
  412. } // namespace ash
  413. #endif // ASH_WM_OVERVIEW_OVERVIEW_SESSION_H_