1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134

ash / wm / mru_window_tracker.h [blame]

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_WM_MRU_WINDOW_TRACKER_H_
#define ASH_WM_MRU_WINDOW_TRACKER_H_

#include <vector>

#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "ui/aura/window_observer.h"
#include "ui/wm/public/activation_change_observer.h"

namespace ash {

enum DesksMruType {
  // The MRU window list will include windows from all active and inactive
  // desks.
  kAllDesks,

  // The MRU window list will exclude windows from the inactive desks.
  //
  // NOTE: During an on-going desk-switch animation, getting the MRU window list
  // for the active desk can be inconsistent, depending on at which stage of the
  // animation it is done. If you want the MRU windows in the soon-to-be active
  // desk, then wait for the animation to finish.
  kActiveDesk,
};

// A predicate that determines whether `window` can be included in the MRU
// window list.
bool CanIncludeWindowInMruList(aura::Window* window);

// A predicate that determines whether `window` is an app type.
bool CanIncludeWindowInAppMruList(aura::Window* window);

// Maintains a most recently used list of windows. This is used for window
// cycling using Alt+Tab and overview mode.
class ASH_EXPORT MruWindowTracker : public wm::ActivationChangeObserver,
                                    public aura::WindowObserver {
 public:
  using WindowList = std::vector<raw_ptr<aura::Window, VectorExperimental>>;

  MruWindowTracker();

  MruWindowTracker(const MruWindowTracker&) = delete;
  MruWindowTracker& operator=(const MruWindowTracker&) = delete;

  ~MruWindowTracker() override;

  // Returns the set windows in the mru list regardless of whether they can be
  // included in the cycler or not.
  // |desks_mru_type| determines whether to include or exclude windows from the
  // inactive desks.
  // TODO(oshima|afakhry): Investigate if we can consolidate BuildXXXList
  // methods with parameters.
  WindowList BuildAppWindowList(DesksMruType desks_mru_type) const;

  // Returns the set of windows which can be cycled through using the tracked
  // list of most recently used windows.
  // |desks_mru_type| determines whether to include or exclude windows from the
  // inactive desks.
  WindowList BuildMruWindowList(DesksMruType desks_mru_type) const;

  // This does the same thing as the above, but ignores the system modal dialog
  // state and hence the returned list could contain more windows if a system
  // modal dialog window is present.
  // |desks_mru_type| determines whether to include or exclude windows from the
  // inactive desks.
  WindowList BuildWindowListIgnoreModal(DesksMruType desks_mru_type) const;

  // This does the same thing as |BuildMruWindowList()| but with some
  // exclusions. This list is used for cycling through by the keyboard via
  // alt-tab.
  // |desks_mru_type| determines whether to include or exclude windows from the
  // inactive desks.
  WindowList BuildWindowForCycleList(DesksMruType desks_mru_type) const;

  // This does the same thing as |BuildWindowForCycleList()| but includes
  // ARC PIP windows if they exist. Entering PIP for Android can consume the
  // window (in contrast to Chrome PIP, which creates a new window). To support
  // the same interaction as Chrome PIP auto-pip, include the Android PIP window
  // in alt-tab. This will let alt tabbing back to the 'original window' restore
  // that window from PIP, which matches behaviour for Chrome PIP, where
  // alt-tabbing back to the original Chrome tab or app ends auto-PIP.
  WindowList BuildWindowForCycleWithPipList(DesksMruType desks_mru_type) const;

  // Starts or stops ignoring window activations. If no longer ignoring
  // activations the currently active window is moved to the front of the
  // MRU window list. Used by WindowCycleList to avoid adding all cycled
  // windows to the front of the MRU window list.
  void SetIgnoreActivations(bool ignore);

  // Called after |window| moved out of its about-to-be-removed desk, to a new
  // target desk's container. This causes |window| to be made the least-recently
  // used window across all desks.
  void OnWindowMovedOutFromRemovingDesk(aura::Window* window);

  // Called when a window is moved to another desk or created by a window
  // restore feature. This function should be only called by
  // `WindowRestoreController`.
  void OnWindowAlteredByWindowRestore(aura::Window* window);

  const std::vector<raw_ptr<aura::Window, VectorExperimental>>&
  GetMruWindowsForTesting() {
    return mru_windows_;
  }

 private:
  // Updates the `mru_windows_` list to insert/move `active_window` at/to the
  // back.
  void SetActiveWindow(aura::Window* active_window);

  // wm::ActivationChangeObserver:
  void OnWindowActivated(ActivationReason reason,
                         aura::Window* gained_active,
                         aura::Window* lost_active) override;

  // aura::WindowObserver:
  void OnWindowDestroyed(aura::Window* window) override;

  // List of windows that have been activated in containers that we cycle
  // through, sorted such that the most recently used window comes last. Note
  // that this ordering differs from the lists returned by the
  // `Build*Window*List` functions, which are reversed.
  std::vector<raw_ptr<aura::Window, VectorExperimental>> mru_windows_;

  bool ignore_window_activations_ = false;
};

}  // namespace ash

#endif  // ASH_WM_MRU_WINDOW_TRACKER_H_