123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef ASH_WM_OVERVIEW_OVERVIEW_SESSION_H_
- #define ASH_WM_OVERVIEW_OVERVIEW_SESSION_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <vector>
- #include "ash/ash_export.h"
- #include "ash/public/cpp/shelf_types.h"
- #include "ash/public/cpp/tablet_mode_observer.h"
- #include "ash/shell_observer.h"
- #include "ash/wm/desks/desks_controller.h"
- #include "ash/wm/overview/overview_types.h"
- #include "ash/wm/overview/scoped_overview_hide_windows.h"
- #include "ash/wm/splitview/split_view_controller.h"
- #include "ash/wm/splitview/split_view_drag_indicators.h"
- #include "ash/wm/splitview/split_view_observer.h"
- #include "base/containers/flat_set.h"
- #include "base/guid.h"
- #include "base/scoped_observation.h"
- #include "base/time/time.h"
- #include "ui/aura/window_observer.h"
- #include "ui/display/display_observer.h"
- #include "ui/events/event_handler.h"
- #include "ui/wm/public/activation_change_observer.h"
- namespace gfx {
- class PointF;
- } // namespace gfx
- namespace ui {
- class KeyEvent;
- } // namespace ui
- namespace views {
- class Widget;
- } // namespace views
- namespace ash {
- class OverviewDelegate;
- class OverviewGrid;
- class OverviewHighlightController;
- class OverviewItem;
- class OverviewWindowDragController;
- class SavedDeskDialogController;
- class SavedDeskPresenter;
- // The Overview shows a grid of all of your windows, allowing to select
- // one by clicking or tapping on it.
- class ASH_EXPORT OverviewSession : public display::DisplayObserver,
- public aura::WindowObserver,
- public ui::EventHandler,
- public ShellObserver,
- public SplitViewObserver,
- public TabletModeObserver,
- public DesksController::Observer {
- public:
- using WindowList = std::vector<aura::Window*>;
- explicit OverviewSession(OverviewDelegate* delegate);
- OverviewSession(const OverviewSession&) = delete;
- OverviewSession& operator=(const OverviewSession&) = delete;
- ~OverviewSession() override;
- // Initialize with the windows that can be selected.
- void Init(const WindowList& windows, const WindowList& hide_windows);
- // Perform cleanup that cannot be done in the destructor.
- void Shutdown();
- // Called when the last overview item from a grid is deleted.
- void OnGridEmpty();
- // Moves the current selection forwards or backwards.
- void IncrementSelection(bool forward);
- // Accepts current selection if any. Returns true if a selection was made,
- // false otherwise.
- bool AcceptSelection();
- // Activates |item's| window.
- void SelectWindow(OverviewItem* item);
- // Sets the dragged window on the split view drag indicators.
- void SetSplitViewDragIndicatorsDraggedWindow(aura::Window* dragged_window);
- // If |state_on_root_window_being_dragged_in| is kNoDrag, this function sets
- // the state on every root window to kNoDrag. Otherwise it sets the state on
- // |root_window_being_dragged_in| to |state_on_root_window_being_dragged_in|,
- // and sets the state on other root windows to kOtherDisplay.
- void UpdateSplitViewDragIndicatorsWindowDraggingStates(
- const aura::Window* root_window_being_dragged_in,
- SplitViewDragIndicators::WindowDraggingState
- state_on_root_window_being_dragged_in);
- // Sets the state on every root window to kNoDrag.
- void ResetSplitViewDragIndicatorsWindowDraggingStates();
- // See |OverviewGrid::RearrangeDuringDrag|.
- void RearrangeDuringDrag(OverviewItem* dragged_item);
- // Updates the appearance of each drop target to visually indicate when the
- // dragged window is being dragged over it.
- void UpdateDropTargetsBackgroundVisibilities(
- OverviewItem* dragged_item,
- const gfx::PointF& location_in_screen);
- // Retrieves the window grid whose root window matches |root_window|. Returns
- // nullptr if the window grid is not found.
- OverviewGrid* GetGridWithRootWindow(aura::Window* root_window);
- // Adds |window| at the specified |index| into the grid with the same root
- // window. Does nothing if that grid does not exist in |grid_list_| or already
- // contains |window|. If |reposition| is true, repositions all items in the
- // target grid (unless it already contained |window|), except those in
- // |ignored_items|. If |animate| is true, animates the repositioning.
- // |animate| has no effect if |reposition| is false.
- void AddItem(aura::Window* window,
- bool reposition,
- bool animate,
- const base::flat_set<OverviewItem*>& ignored_items,
- size_t index);
- // Similar to the above function, but adds the window at the end of the grid.
- // This will use the spawn-item animation.
- // TODO(afakhry): Expose |use_spawn_animation| if needed.
- void AppendItem(aura::Window* window, bool reposition, bool animate);
- // Like |AddItem|, but adds |window| at the correct position according to MRU
- // order. If |reposition|, |animate|, and |restack| are all true, the stacking
- // order will be adjusted after the animation. If |restack| is true but at
- // least one of |reposition| and |animate| is false, the stacking order will
- // be adjusted immediately.
- void AddItemInMruOrder(aura::Window* window,
- bool reposition,
- bool animate,
- bool restack,
- bool use_spawn_animation);
- // Removes |overview_item| from the corresponding grid.
- void RemoveItem(OverviewItem* overview_item);
- void RemoveItem(OverviewItem* overview_item,
- bool item_destroying,
- bool reposition);
- void RemoveDropTargets();
- void InitiateDrag(OverviewItem* item,
- const gfx::PointF& location_in_screen,
- bool is_touch_dragging);
- void Drag(OverviewItem* item, const gfx::PointF& location_in_screen);
- void CompleteDrag(OverviewItem* item, const gfx::PointF& location_in_screen);
- void StartNormalDragMode(const gfx::PointF& location_in_screen);
- void Fling(OverviewItem* item,
- const gfx::PointF& location_in_screen,
- float velocity_x,
- float velocity_y);
- void ActivateDraggedWindow();
- void ResetDraggedWindowGesture();
- // Called when a window (either it's browser window or an app window)
- // start/continue/end being dragged in tablet mode by swiping from the top
- // of the screen to drag from top or by swiping from the shelf to drag from
- // bottom .
- // TODO(xdai): Currently it doesn't work for multi-display scenario.
- void OnWindowDragStarted(aura::Window* dragged_window, bool animate);
- void OnWindowDragContinued(
- aura::Window* dragged_window,
- const gfx::PointF& location_in_screen,
- SplitViewDragIndicators::WindowDraggingState window_dragging_state);
- void OnWindowDragEnded(aura::Window* dragged_window,
- const gfx::PointF& location_in_screen,
- bool should_drop_window_into_overview,
- bool snap);
- // Shows or Hides all windows (including drop target window & desk widget) in
- // overview. It's used when dragging a window from bottom, when the user slows
- // down or stops dragging the window, shows overview windows and when the user
- // resumes dragging, hides overview windows.
- void SetVisibleDuringWindowDragging(bool visible, bool animate);
- // This is called on drag end for WebUI Tab Strip similar to
- // OnWindowDragEnded. Since WebUI tab strip tab dragging only creates new
- // window on drag end, both OnWindowDragStarted and OnWindowDragContinued are
- // not being called.
- void MergeWindowIntoOverviewForWebUITabStrip(aura::Window* dragged_window);
- // Positions all overview items except those in |ignored_items|.
- void PositionWindows(bool animate,
- const base::flat_set<OverviewItem*>& ignored_items = {});
- // Returns true if |window| is currently showing in overview.
- bool IsWindowInOverview(const aura::Window* window);
- // Returns the overview item for |window|, or nullptr if |window| doesn't have
- // a corresponding item in overview mode.
- OverviewItem* GetOverviewItemForWindow(const aura::Window* window);
- // Set the window grid that's displaying in |root_window| not animate when
- // exiting overview mode, i.e., all window items in the grid will not animate
- // when exiting overview mode. It may be called in two cases: 1) When a window
- // gets snapped (either from overview or not) and thus cause the end of the
- // overview mode, we should not do the exiting animation; 2) When a window
- // is dragged around and when released, it causes the end of the overview
- // mode, we also should not do the exiting animation.
- void SetWindowListNotAnimatedWhenExiting(aura::Window* root_window);
- // Shifts and fades the grid in |grid_list_| associated with |location|.
- // Updates all the overview items' mask and shadow.
- void UpdateRoundedCornersAndShadow();
- // Called when the overview mode starting animation completes. |canceled| is
- // true when the starting animation is interrupted by ending overview mode. If
- // |canceled| is false and |should_focus_overview| is true, then
- // |overview_focus_widget_| shall gain focus. |should_focus_overview| has no
- // effect when |canceled| is true.
- void OnStartingAnimationComplete(bool canceled, bool should_focus_overview);
- // Called when windows are being activated/deactivated during
- // overview mode.
- void OnWindowActivating(
- ::wm::ActivationChangeObserver::ActivationReason reason,
- aura::Window* gained_active,
- aura::Window* lost_active);
- // Returns true when either the `DesksTemplatesGridWidget` or
- // `SavedDeskDialog` is the window that is losing activation.
- bool IsTemplatesUiLosingActivation(aura::Window* lost_active);
- // Gets the window which keeps focus for the duration of overview mode.
- aura::Window* GetOverviewFocusWindow();
- // Returns the window highlighted by the selector widget.
- aura::Window* GetHighlightedWindow();
- // Suspends/Resumes window re-positiong in overview.
- void SuspendReposition();
- void ResumeReposition();
- // Returns true if all its window grids don't have any window item.
- bool IsEmpty() const;
- // If |restore| is true, activate window |active_window_before_overview_|.
- // This is usually called when exiting overview to restore window activation
- // to the window that was active before entering overview. If |restore| is
- // false, reset |active_window_before_overview_| to nullptr so that window
- // activation will not be restore when overview is ended.
- void RestoreWindowActivation(bool restore);
- // Handles requests to active or close the currently highlighted |item|.
- void OnHighlightedItemActivated(OverviewItem* item);
- void OnHighlightedItemClosed(OverviewItem* item);
- // Called explicitly (with no list of observers) by the |RootWindowController|
- // of |root|, so that the associated grid is properly removed and destroyed.
- // Note: Usually, when a display is removed, it causes a window activation
- // which ends overview mode, and then this function does not get called. This
- // function is only needed for when overview mode cannot be ended (see
- // |OverviewController::CanEndOverview| and https://crbug.com/1024325).
- void OnRootWindowClosing(aura::Window* root);
- // Returns the current dragged overview item if any. Note that windows that
- // are dragged into overview from the shelf don't have an OverviewItem while
- // dragging.
- OverviewItem* GetCurrentDraggedOverviewItem() const;
- // Overview objects which handle events (OverviewItemView,
- // OverviewGridEventHandler) should call this function to check if they can
- // process an event. Returns false if an overview item other than |sender|
- // (which may be nullptr in the case of events on the wallpaper) is already
- // being dragged, or if a window is currently being dragged from the bottom.
- // This is so we can allow switching finger while dragging, but not allow
- // dragging two or more items. The first |CanProcessEvent()| calls the second
- // with |sender| as nullptr (i.e. event processed by
- // OverviewGridEventHandler). When |sender| is nullptr, |from_touch_gesture|
- // does not matter.
- bool CanProcessEvent() const;
- bool CanProcessEvent(OverviewItem* sender, bool from_touch_gesture) const;
- // Returns true if |window| is not nullptr and equals
- // |active_window_before_overview_|.
- bool IsWindowActiveWindowBeforeOverview(aura::Window* window) const;
- // Shows the desks templates grids on all displays. If `was_zero_state` is
- // true then we will expand the desks bars. Focuses the item which matches
- // `item_to_focus` on the display associated with `root_window`.
- void ShowDesksTemplatesGrids(bool was_zero_state,
- const base::GUID& item_to_focus,
- const std::u16string& saved_desk_name,
- aura::Window* const root_window);
- void HideDesksTemplatesGrids();
- bool IsShowingDesksTemplatesGrid() const;
- // Updates the focusable overview widgets so that they point to the correct
- // next and previous widgets for a11y purposes. Needs to be updated when a
- // piece of UI is shown or hidden.
- void UpdateAccessibilityFocus();
- // DesksController::Observer:
- void OnDeskAdded(const Desk* desk) override;
- void OnDeskRemoved(const Desk* desk) override;
- void OnDeskReordered(int old_index, int new_index) override;
- void OnDeskActivationChanged(const Desk* activated,
- const Desk* deactivated) override;
- void OnDeskSwitchAnimationLaunching() override;
- void OnDeskSwitchAnimationFinished() override;
- void OnDeskNameChanged(const Desk* desk,
- const std::u16string& new_name) override;
- // display::DisplayObserver:
- void OnDisplayAdded(const display::Display& display) override;
- void OnDisplayMetricsChanged(const display::Display& display,
- uint32_t metrics) override;
- // aura::WindowObserver:
- void OnWindowDestroying(aura::Window* window) override;
- void OnWindowAdded(aura::Window* new_window) override;
- // ui::EventHandler:
- void OnKeyEvent(ui::KeyEvent* event) override;
- // ShellObserver:
- void OnShellDestroying() override;
- void OnShelfAlignmentChanged(aura::Window* root_window,
- ShelfAlignment old_alignment) override;
- void OnUserWorkAreaInsetsChanged(aura::Window* root_window) override;
- // SplitViewObserver:
- void OnSplitViewStateChanged(SplitViewController::State previous_state,
- SplitViewController::State state) override;
- void OnSplitViewDividerPositionChanged() override;
- // TabletModeObserver:
- void OnTabletModeStarted() override;
- void OnTabletModeEnded() override;
- void UpdateFrameThrottling();
- OverviewDelegate* delegate() { return delegate_; }
- bool is_shutting_down() const { return is_shutting_down_; }
- void set_is_shutting_down(bool is_shutting_down) {
- is_shutting_down_ = is_shutting_down;
- }
- const std::vector<std::unique_ptr<OverviewGrid>>& grid_list() const {
- return grid_list_;
- }
- size_t num_items() const { return num_items_; }
- OverviewEnterExitType enter_exit_overview_type() const {
- return enter_exit_overview_type_;
- }
- void set_enter_exit_overview_type(OverviewEnterExitType val) {
- enter_exit_overview_type_ = val;
- }
- OverviewWindowDragController* window_drag_controller() {
- return window_drag_controller_.get();
- }
- OverviewHighlightController* highlight_controller() {
- return highlight_controller_.get();
- }
- SavedDeskPresenter* saved_desk_presenter() {
- return saved_desk_presenter_.get();
- }
- SavedDeskDialogController* saved_desk_dialog_controller() {
- return saved_desk_dialog_controller_.get();
- }
- void set_auto_add_windows_enabled(bool enabled) {
- auto_add_windows_enabled_ = enabled;
- }
- void set_allow_empty_desk_without_exiting(bool enabled) {
- allow_empty_desk_without_exiting_ = enabled;
- }
- private:
- friend class DesksAcceleratorsTest;
- friend class OverviewTestBase;
- // Called when tablet mode changes.
- void OnTabletModeChanged();
- // Helper function that moves the highlight forward or backward on the
- // corresponding window grid.
- void Move(bool reverse);
- // Helper function that processes a key event and maybe scrolls the overview
- // grid on the primary display.
- bool ProcessForScrolling(const ui::KeyEvent& event);
- // Removes all observers that were registered during construction and/or
- // initialization.
- void RemoveAllObservers();
- // Updates the no windows widget on each OverviewGrid.
- void UpdateNoWindowsWidgetOnEachGrid();
- // Refreshes the bounds of the no windows widget on each OverviewGrid.
- void RefreshNoWindowsWidgetBoundsOnEachGrid(bool animate);
- void OnItemAdded(aura::Window* window);
- // Called when a window is activated or deactivated and the saved desk feature
- // is enabled. Returns true if we should keep overview open. Overview should
- // be kept open if `gained_active` or `lost_active` is a saved desk dialog.
- bool ShouldKeepOverviewOpenForSavedDeskDialog(aura::Window* gained_active,
- aura::Window* lost_active);
- // Weak pointer to the overview delegate which will be called when a selection
- // is made.
- OverviewDelegate* delegate_;
- // A weak pointer to the window which was active on starting overview. If
- // overview is canceled the activation should be restored to this window.
- aura::Window* active_window_before_overview_ = nullptr;
- // A hidden window that receives focus while in overview mode. It is needed
- // because accessibility needs something focused for it to work and we cannot
- // use one of the overview windows otherwise wm::ActivateWindow will not
- // work.
- // TODO(sammiequon): Focus the grid desks widget if it is always available, or
- // we may be able to add some mechanism to trigger accessibility events
- // without a focused window.
- std::unique_ptr<views::Widget> overview_focus_widget_;
- // True when performing operations that may cause window activations. This is
- // used to prevent handling the resulting expected activation. This is
- // initially true until this is initialized.
- bool ignore_activations_ = true;
- // True when overview mode is exiting.
- bool is_shutting_down_ = false;
- // List of all the window overview grids, one for each root window.
- std::vector<std::unique_ptr<OverviewGrid>> grid_list_;
- // The following variables are used for metric collection purposes. All of
- // them refer to this particular overview session and are not cumulative:
- // The time when overview was started.
- base::Time overview_start_time_;
- // The number of arrow key presses.
- size_t num_key_presses_ = 0;
- // The number of items in the overview.
- size_t num_items_ = 0;
- // True if we are currently using keyboard (control + left/right) to scroll
- // through the grid.
- bool is_keyboard_scrolling_grid_ = false;
- // Stores the overview enter/exit type. See the enum declaration for
- // information on how these types affect overview mode.
- OverviewEnterExitType enter_exit_overview_type_ =
- OverviewEnterExitType::kNormal;
- // The selected item when exiting overview mode. nullptr if no window
- // selected.
- OverviewItem* selected_item_ = nullptr;
- // The drag controller for a window in the overview mode.
- std::unique_ptr<OverviewWindowDragController> window_drag_controller_;
- std::unique_ptr<ScopedOverviewHideWindows> hide_overview_windows_;
- std::unique_ptr<OverviewHighlightController> highlight_controller_;
- // The object responsible to talking to the desk model.
- std::unique_ptr<SavedDeskPresenter> saved_desk_presenter_;
- // Controls showing and hiding dialogs associated with the saved desks
- // feature.
- std::unique_ptr<SavedDeskDialogController> saved_desk_dialog_controller_;
- absl::optional<display::ScopedDisplayObserver> display_observer_;
- // Boolean to indicate whether chromeVox is enabled or not.
- bool chromevox_enabled_;
- // When non-null, windows changes on this desk are observed.
- const Desk* observing_desk_ = nullptr;
- // This is true *while* an overview item is being dynamically added. It is
- // used to avoid recursively adding overview items.
- bool is_adding_new_item_ = false;
- // When true, windows added to the observed desk are automatically added to
- // the overview session.
- bool auto_add_windows_enabled_ = true;
- // When true, the overview session is not exited when the last window is
- // removed.
- bool allow_empty_desk_without_exiting_ = false;
- base::ScopedObservation<TabletModeController, TabletModeObserver>
- tablet_mode_observation_{this};
- base::ScopedObservation<DesksController, DesksController::Observer>
- desks_controller_observation_{this};
- base::ScopedObservation<aura::Window, aura::WindowObserver>
- active_window_before_overview_observation_{this};
- };
- } // namespace ash
- #endif // ASH_WM_OVERVIEW_OVERVIEW_SESSION_H_
|