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_