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
ash / wallpaper / wallpaper_window_state_manager.cc [blame]
// Copyright 2017 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/wallpaper/wallpaper_window_state_manager.h"
#include "base/memory/raw_ptr.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"
namespace ash {
namespace {
// Reactivate the most recently unminimized window on the active desk so as not
// to activate any desk that has been explicitly navigated away from, nor
// activate any window that has been explicitly minimized.
void ActivateMruUnminimizedWindowOnActiveDesk() {
MruWindowTracker::WindowList mru_windows(
Shell::Get()->mru_window_tracker()->BuildMruWindowList(
DesksMruType::kActiveDesk));
for (aura::Window* window : mru_windows) {
if (WindowState::Get(window)->GetStateType() !=
chromeos::WindowStateType::kMinimized) {
WindowState::Get(window)->Activate();
return;
}
}
}
} // namespace
WallpaperWindowStateManager::WallpaperWindowStateManager() = default;
WallpaperWindowStateManager::~WallpaperWindowStateManager() = default;
void WallpaperWindowStateManager::MinimizeInactiveWindows(
const std::string& user_id_hash) {
if (!base::Contains(user_id_hash_window_list_map_, user_id_hash)) {
user_id_hash_window_list_map_[user_id_hash] =
std::set<raw_ptr<aura::Window, SetExperimental>>();
}
std::set<raw_ptr<aura::Window, SetExperimental>>* results =
&user_id_hash_window_list_map_[user_id_hash];
aura::Window* active_window = window_util::GetActiveWindow();
aura::Window::Windows windows =
Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal(
kActiveDesk);
for (aura::Window::Windows::iterator iter = windows.begin();
iter != windows.end(); ++iter) {
// Ignore active window and minimized windows.
if (*iter == active_window || WindowState::Get(*iter)->IsMinimized())
continue;
if (!(*iter)->HasObserver(this))
(*iter)->AddObserver(this);
results->insert(*iter);
WindowState::Get(*iter)->Minimize();
}
}
void WallpaperWindowStateManager::RestoreMinimizedWindows(
const std::string& user_id_hash) {
UserIDHashWindowListMap::iterator it =
user_id_hash_window_list_map_.find(user_id_hash);
if (it == user_id_hash_window_list_map_.end()) {
DVLOG(1) << "No minimized window state saved";
return;
}
std::set<raw_ptr<aura::Window, SetExperimental>> removed_windows;
removed_windows.swap(it->second);
user_id_hash_window_list_map_.erase(it);
for (std::set<raw_ptr<aura::Window, SetExperimental>>::iterator iter =
removed_windows.begin();
iter != removed_windows.end(); ++iter) {
WindowState::Get(*iter)->Unminimize();
RemoveObserverIfUnreferenced(*iter);
}
// If the wallpaper app is closed while the desktop is in overview mode,
// do not activate any window, because doing so will disable overview mode.
if (!Shell::Get()->overview_controller()->InOverviewSession())
ActivateMruUnminimizedWindowOnActiveDesk();
}
void WallpaperWindowStateManager::RemoveObserverIfUnreferenced(
aura::Window* window) {
for (UserIDHashWindowListMap::iterator iter =
user_id_hash_window_list_map_.begin();
iter != user_id_hash_window_list_map_.end(); ++iter) {
if (base::Contains(iter->second, window))
return;
}
// Remove observer if |window| is not observed by any users.
window->RemoveObserver(this);
}
void WallpaperWindowStateManager::OnWindowDestroyed(aura::Window* window) {
for (UserIDHashWindowListMap::iterator iter =
user_id_hash_window_list_map_.begin();
iter != user_id_hash_window_list_map_.end(); ++iter) {
iter->second.erase(window);
}
}
void WallpaperWindowStateManager::OnWindowStackingChanged(
aura::Window* window) {
// If user interacted with the |window| while wallpaper picker is opening,
// removes the |window| from observed list.
for (auto iter = user_id_hash_window_list_map_.begin();
iter != user_id_hash_window_list_map_.end(); ++iter) {
iter->second.erase(window);
}
window->RemoveObserver(this);
}
} // namespace ash