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
135
136
137
138
139
ash / user_education / welcome_tour / welcome_tour_window_minimizer.cc [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/user_education/welcome_tour/welcome_tour_window_minimizer.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shell.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/window_state.h"
#include "base/check.h"
#include "base/task/sequenced_task_runner.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tracker.h"
#include "ui/wm/core/scoped_animation_disabler.h"
namespace ash {
namespace {
// Helpers ---------------------------------------------------------------------
// Returns whether a window's children should be minimized while
// `WelcomeTourWindowMinimizer` exists.
bool ShouldMinimizeChildren(aura::Window* window) {
return window && (desks_util::IsDeskContainer(window) ||
window->GetId() == kShellWindowId_FloatContainer);
}
// Minimizes a window, if it is possible to do so.
void Minimize(aura::Window* window) {
auto* state = WindowState::Get(window);
if (state && !state->IsMinimized()) {
state->Minimize();
}
}
// Minimizes all windows in a `aura::WindowTracker`, if they are in containers
// that should have their windows minimized. Can be called asynchronously.
void MaybeMinimize(aura::WindowTracker* window_tracker) {
for (aura::Window* window : window_tracker->windows()) {
if (ShouldMinimizeChildren(window->parent())) {
wm::ScopedAnimationDisabler animation_disabler(window);
Minimize(window);
}
}
}
} // namespace
// WelcomeTourWindowMinimizer --------------------------------------------------
WelcomeTourWindowMinimizer::WelcomeTourWindowMinimizer() {
for (aura::Window* root_window : Shell::GetAllRootWindows()) {
OnRootWindowAdded(root_window);
}
shell_observation_.Observe(Shell::Get());
}
WelcomeTourWindowMinimizer::~WelcomeTourWindowMinimizer() = default;
void WelcomeTourWindowMinimizer::OnWindowDestroying(aura::Window* window) {
root_window_observations_.RemoveObservation(window);
}
void WelcomeTourWindowMinimizer::OnWindowHierarchyChanged(
const HierarchyChangeParams& params) {
// If the relevant window is entering a container that should be minimized,
// begin keeping it minimized.
if (ShouldMinimizeChildren(params.new_parent)) {
app_window_minimizer_.AddWindow(params.target);
} else if (ShouldMinimizeChildren(params.old_parent)) {
// If the window is leaving a should-minimize container and not entering
// another one, stop keeping it minimized.
app_window_minimizer_.RemoveWindow(params.target);
}
}
void WelcomeTourWindowMinimizer::OnRootWindowAdded(aura::Window* root_window) {
root_window_observations_.AddObservation(root_window);
std::vector<aura::Window*> containers =
desks_util::GetDesksContainers(root_window);
auto* float_container =
root_window->GetChildById(kShellWindowId_FloatContainer);
CHECK(float_container);
containers.push_back(float_container);
for (auto* container : containers) {
if (ShouldMinimizeChildren(container)) {
for (aura::Window* child : container->children()) {
app_window_minimizer_.AddWindow(child);
}
}
}
}
// WelcomeTourMinimized::AppWindowMinimizer ------------------------------------
WelcomeTourWindowMinimizer::AppWindowMinimizer::AppWindowMinimizer() = default;
WelcomeTourWindowMinimizer::AppWindowMinimizer::~AppWindowMinimizer() = default;
void WelcomeTourWindowMinimizer::AppWindowMinimizer::AddWindow(
aura::Window* window) {
Minimize(window);
if (!app_window_observations_.IsObservingSource(window)) {
app_window_observations_.AddObservation(window);
}
}
void WelcomeTourWindowMinimizer::AppWindowMinimizer::RemoveWindow(
aura::Window* window) {
if (app_window_observations_.IsObservingSource(window)) {
app_window_observations_.RemoveObservation(window);
}
}
void WelcomeTourWindowMinimizer::AppWindowMinimizer::OnWindowDestroying(
aura::Window* window) {
app_window_observations_.RemoveObservation(window);
}
void WelcomeTourWindowMinimizer::AppWindowMinimizer::OnWindowVisibilityChanged(
aura::Window* window,
bool visible) {
if (visible) {
// Minimize the window asynchronously to avoid changing visibility directly
// from within a visibility event.
base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
FROM_HERE,
base::BindOnce(&MaybeMinimize,
base::Owned(std::make_unique<aura::WindowTracker>(
aura::WindowTracker::WindowList{window}))));
}
}
} // namespace ash