Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: ash/wm/overview/window_selector.cc

Issue 23654037: Add panels as a single group of windows per display for overview window cycling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix restored panel relayout when some panels minimized. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/wm/overview/window_selector.h ('k') | ash/wm/overview/window_selector_item.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/overview/window_selector.h" 5 #include "ash/wm/overview/window_selector.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "ash/wm/mru_window_tracker.h" 10 #include "ash/wm/mru_window_tracker.h"
11 #include "ash/wm/overview/window_overview.h" 11 #include "ash/wm/overview/window_overview.h"
12 #include "ash/wm/overview/window_selector_delegate.h" 12 #include "ash/wm/overview/window_selector_delegate.h"
13 #include "ash/wm/overview/window_selector_panels.h"
13 #include "ash/wm/overview/window_selector_window.h" 14 #include "ash/wm/overview/window_selector_window.h"
15 #include "ash/wm/window_settings.h"
14 #include "base/auto_reset.h" 16 #include "base/auto_reset.h"
15 #include "base/timer/timer.h" 17 #include "base/timer/timer.h"
16 #include "ui/aura/client/activation_client.h" 18 #include "ui/aura/client/activation_client.h"
17 #include "ui/aura/client/focus_client.h" 19 #include "ui/aura/client/focus_client.h"
18 #include "ui/aura/root_window.h" 20 #include "ui/aura/root_window.h"
19 #include "ui/aura/window.h" 21 #include "ui/aura/window.h"
20 #include "ui/base/events/event.h" 22 #include "ui/base/events/event.h"
21 #include "ui/base/events/event_handler.h" 23 #include "ui/base/events/event_handler.h"
22 24
23 namespace ash { 25 namespace ash {
24 26
25 namespace { 27 namespace {
26 28
27 const int kOverviewDelayOnCycleMilliseconds = 300; 29 const int kOverviewDelayOnCycleMilliseconds = 300;
28 30
29 // A comparator for locating a given target window. 31 // A comparator for locating a given target window.
30 struct WindowSelectorWindowComparator 32 struct WindowSelectorItemComparator
31 : public std::unary_function<WindowSelectorWindow*, bool> { 33 : public std::unary_function<WindowSelectorItem*, bool> {
32 explicit WindowSelectorWindowComparator(const aura::Window* target_window) 34 explicit WindowSelectorItemComparator(const aura::Window* target_window)
33 : target(target_window) { 35 : target(target_window) {
34 } 36 }
35 37
36 bool operator()(const WindowSelectorWindow* window) const { 38 bool operator()(const WindowSelectorItem* window) const {
37 return target == window->window(); 39 return window->TargetedWindow(target) != NULL;
38 } 40 }
39 41
40 const aura::Window* target; 42 const aura::Window* target;
41 }; 43 };
42 44
45 // A comparator for locating a selector item for a given root.
46 struct WindowSelectorItemForRoot
47 : public std::unary_function<WindowSelectorItem*, bool> {
48 explicit WindowSelectorItemForRoot(const aura::RootWindow* root)
49 : root_window(root) {
50 }
51
52 bool operator()(const WindowSelectorItem* item) const {
53 return item->GetRootWindow() == root_window;
54 }
55
56 const aura::RootWindow* root_window;
57 };
58
43 // Filter to watch for the termination of a keyboard gesture to cycle through 59 // Filter to watch for the termination of a keyboard gesture to cycle through
44 // multiple windows. 60 // multiple windows.
45 class WindowSelectorEventFilter : public ui::EventHandler { 61 class WindowSelectorEventFilter : public ui::EventHandler {
46 public: 62 public:
47 WindowSelectorEventFilter(WindowSelector* selector); 63 WindowSelectorEventFilter(WindowSelector* selector);
48 virtual ~WindowSelectorEventFilter(); 64 virtual ~WindowSelectorEventFilter();
49 65
50 // Overridden from ui::EventHandler: 66 // Overridden from ui::EventHandler:
51 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE; 67 virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE;
52 68
(...skipping 30 matching lines...) Expand all
83 WindowSelectorDelegate* delegate) 99 WindowSelectorDelegate* delegate)
84 : mode_(mode), 100 : mode_(mode),
85 start_overview_timer_(FROM_HERE, 101 start_overview_timer_(FROM_HERE,
86 base::TimeDelta::FromMilliseconds(kOverviewDelayOnCycleMilliseconds), 102 base::TimeDelta::FromMilliseconds(kOverviewDelayOnCycleMilliseconds),
87 this, &WindowSelector::StartOverview), 103 this, &WindowSelector::StartOverview),
88 delegate_(delegate), 104 delegate_(delegate),
89 selected_window_(0), 105 selected_window_(0),
90 restore_focus_window_(NULL), 106 restore_focus_window_(NULL),
91 restoring_focus_(false) { 107 restoring_focus_(false) {
92 DCHECK(delegate_); 108 DCHECK(delegate_);
109 std::vector<WindowSelectorPanels*> panels_items;
110 for (size_t i = 0; i < windows.size(); ++i) {
111 windows[i]->AddObserver(this);
112 observed_windows_.insert(windows[i]);
113
114 if (windows[i]->type() == aura::client::WINDOW_TYPE_PANEL &&
115 wm::GetWindowSettings(windows[i])->panel_attached()) {
116 // Attached panel windows are grouped into a single overview item per
117 // root window (display).
118 std::vector<WindowSelectorPanels*>::iterator iter =
119 std::find_if(panels_items.begin(), panels_items.end(),
120 WindowSelectorItemForRoot(windows[i]->GetRootWindow()));
121 WindowSelectorPanels* panels_item = NULL;
122 if (iter == panels_items.end()) {
123 panels_item = new WindowSelectorPanels();
124 panels_items.push_back(panels_item);
125 windows_.push_back(panels_item);
126 } else {
127 panels_item = *iter;
128 }
129 panels_item->AddWindow(windows[i]);
130 } else {
131 windows_.push_back(new WindowSelectorWindow(windows[i]));
132 }
133 }
93 RemoveFocusAndSetRestoreWindow(); 134 RemoveFocusAndSetRestoreWindow();
94 for (size_t i = 0; i < windows.size(); ++i) {
95 // restore_focus_window_ is already observed from the call to
96 // RemoveFocusAndSetRestoreWindow.
97 if (windows[i] != restore_focus_window_)
98 windows[i]->AddObserver(this);
99 windows_.push_back(new WindowSelectorWindow(windows[i]));
100 }
101 135
102 // Observe window activations and switchable containers on all root windows 136 // Observe window activations and switchable containers on all root windows
103 // for newly created windows during overview. 137 // for newly created windows during overview.
104 Shell::GetInstance()->activation_client()->AddObserver(this); 138 Shell::GetInstance()->activation_client()->AddObserver(this);
105 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 139 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
106 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); 140 for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
107 iter != root_windows.end(); ++iter) { 141 iter != root_windows.end(); ++iter) {
108 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 142 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
109 Shell::GetContainer(*iter, 143 Shell::GetContainer(*iter,
110 kSwitchableWindowContainerIds[i])->AddObserver(this); 144 kSwitchableWindowContainerIds[i])->AddObserver(this);
111 } 145 }
112 } 146 }
113 147
114 if (mode == WindowSelector::CYCLE) { 148 if (mode == WindowSelector::CYCLE) {
115 event_handler_.reset(new WindowSelectorEventFilter(this)); 149 event_handler_.reset(new WindowSelectorEventFilter(this));
116 start_overview_timer_.Reset(); 150 start_overview_timer_.Reset();
117 } else { 151 } else {
118 StartOverview(); 152 StartOverview();
119 } 153 }
120 } 154 }
121 155
122 WindowSelector::~WindowSelector() { 156 WindowSelector::~WindowSelector() {
123 ResetFocusRestoreWindow(true); 157 ResetFocusRestoreWindow(true);
124 for (size_t i = 0; i < windows_.size(); i++) { 158 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin();
125 windows_[i]->window()->RemoveObserver(this); 159 iter != observed_windows_.end(); ++iter) {
160 (*iter)->RemoveObserver(this);
126 } 161 }
127 Shell::GetInstance()->activation_client()->RemoveObserver(this); 162 Shell::GetInstance()->activation_client()->RemoveObserver(this);
128 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 163 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
129 for (Shell::RootWindowList::const_iterator iter = root_windows.begin(); 164 for (Shell::RootWindowList::const_iterator iter = root_windows.begin();
130 iter != root_windows.end(); ++iter) { 165 iter != root_windows.end(); ++iter) {
131 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 166 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
132 Shell::GetContainer(*iter, 167 Shell::GetContainer(*iter,
133 kSwitchableWindowContainerIds[i])->RemoveObserver(this); 168 kSwitchableWindowContainerIds[i])->RemoveObserver(this);
134 } 169 }
135 } 170 }
136 } 171 }
137 172
138 void WindowSelector::Step(WindowSelector::Direction direction) { 173 void WindowSelector::Step(WindowSelector::Direction direction) {
139 DCHECK_EQ(CYCLE, mode_); 174 DCHECK_EQ(CYCLE, mode_);
140 DCHECK(!windows_.empty()); 175 DCHECK(!windows_.empty());
141 selected_window_ = (selected_window_ + windows_.size() + 176 selected_window_ = (selected_window_ + windows_.size() +
142 (direction == WindowSelector::FORWARD ? 1 : -1)) % windows_.size(); 177 (direction == WindowSelector::FORWARD ? 1 : -1)) % windows_.size();
143 if (window_overview_) { 178 if (window_overview_) {
144 window_overview_->SetSelection(selected_window_); 179 window_overview_->SetSelection(selected_window_);
145 } else { 180 } else {
146 aura::Window* current_window = windows_[selected_window_]->window(); 181 aura::Window* current_window =
182 windows_[selected_window_]->SelectionWindow();
147 current_window->Show(); 183 current_window->Show();
148 current_window->SetTransform(gfx::Transform()); 184 current_window->SetTransform(gfx::Transform());
149 current_window->parent()->StackChildAtTop(current_window); 185 current_window->parent()->StackChildAtTop(current_window);
150 start_overview_timer_.Reset(); 186 start_overview_timer_.Reset();
151 } 187 }
152 } 188 }
153 189
154 void WindowSelector::SelectWindow() { 190 void WindowSelector::SelectWindow() {
155 ResetFocusRestoreWindow(false); 191 ResetFocusRestoreWindow(false);
156 SelectWindow(windows_[selected_window_]->window()); 192 SelectWindow(windows_[selected_window_]->SelectionWindow());
157 } 193 }
158 194
159 void WindowSelector::SelectWindow(aura::Window* window) { 195 void WindowSelector::SelectWindow(aura::Window* window) {
160 ScopedVector<WindowSelectorWindow>::iterator iter = 196 ScopedVector<WindowSelectorItem>::iterator iter =
161 std::find_if(windows_.begin(), windows_.end(), 197 std::find_if(windows_.begin(), windows_.end(),
162 WindowSelectorWindowComparator(window)); 198 WindowSelectorItemComparator(window));
163 DCHECK(iter != windows_.end()); 199 DCHECK(iter != windows_.end());
164 // The selected window should not be minimized when window selection is 200 // The selected window should not be minimized when window selection is
165 // ended. 201 // ended.
166 (*iter)->RestoreWindowOnExit(); 202 (*iter)->RestoreWindowOnExit(window);
167 delegate_->OnWindowSelected(window); 203 delegate_->OnWindowSelected(window);
168 } 204 }
169 205
170 void WindowSelector::CancelSelection() { 206 void WindowSelector::CancelSelection() {
171 delegate_->OnSelectionCanceled(); 207 delegate_->OnSelectionCanceled();
172 } 208 }
173 209
174 void WindowSelector::OnWindowAdded(aura::Window* new_window) { 210 void WindowSelector::OnWindowAdded(aura::Window* new_window) {
175 if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL && 211 if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL &&
176 new_window->type() != aura::client::WINDOW_TYPE_PANEL) { 212 new_window->type() != aura::client::WINDOW_TYPE_PANEL) {
177 return; 213 return;
178 } 214 }
179 215
180 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 216 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
181 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && 217 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] &&
182 !new_window->transient_parent()) { 218 !new_window->transient_parent()) {
183 // The new window is in one of the switchable containers, abort overview. 219 // The new window is in one of the switchable containers, abort overview.
184 CancelSelection(); 220 CancelSelection();
185 return; 221 return;
186 } 222 }
187 } 223 }
188 } 224 }
189 225
190 void WindowSelector::OnWindowDestroyed(aura::Window* window) { 226 void WindowSelector::OnWindowDestroyed(aura::Window* window) {
191 ScopedVector<WindowSelectorWindow>::iterator iter = 227 ScopedVector<WindowSelectorItem>::iterator iter =
192 std::find_if(windows_.begin(), windows_.end(), 228 std::find_if(windows_.begin(), windows_.end(),
193 WindowSelectorWindowComparator(window)); 229 WindowSelectorItemComparator(window));
194 DCHECK(window == restore_focus_window_ || iter != windows_.end()); 230 DCHECK(window == restore_focus_window_ || iter != windows_.end());
195 window->RemoveObserver(this); 231 window->RemoveObserver(this);
196 if (window == restore_focus_window_) 232 if (window == restore_focus_window_)
197 restore_focus_window_ = NULL; 233 restore_focus_window_ = NULL;
198 if (iter == windows_.end()) 234 if (iter == windows_.end())
199 return; 235 return;
200 236
237 observed_windows_.erase(window);
238 (*iter)->RemoveWindow(window);
239 // If there are still windows in this selector entry then the overview is
240 // still active and the active selection remains the same.
241 if (!(*iter)->empty())
242 return;
243
201 size_t deleted_index = iter - windows_.begin(); 244 size_t deleted_index = iter - windows_.begin();
202 (*iter)->OnWindowDestroyed();
203 windows_.erase(iter); 245 windows_.erase(iter);
204 if (windows_.empty()) { 246 if (windows_.empty()) {
205 CancelSelection(); 247 CancelSelection();
206 return; 248 return;
207 } 249 }
208 window_overview_->OnWindowsChanged(); 250 if (window_overview_)
251 window_overview_->OnWindowsChanged();
209 if (mode_ == CYCLE && selected_window_ >= deleted_index) { 252 if (mode_ == CYCLE && selected_window_ >= deleted_index) {
210 if (selected_window_ > deleted_index) 253 if (selected_window_ > deleted_index)
211 selected_window_--; 254 selected_window_--;
212 selected_window_ = selected_window_ % windows_.size(); 255 selected_window_ = selected_window_ % windows_.size();
213 if (window_overview_) 256 if (window_overview_)
214 window_overview_->SetSelection(selected_window_); 257 window_overview_->SetSelection(selected_window_);
215 } 258 }
216 } 259 }
217 260
218 void WindowSelector::OnWindowActivated(aura::Window* gained_active, 261 void WindowSelector::OnWindowActivated(aura::Window* gained_active,
(...skipping 22 matching lines...) Expand all
241 window_overview_->SetSelection(selected_window_); 284 window_overview_->SetSelection(selected_window_);
242 } 285 }
243 286
244 void WindowSelector::RemoveFocusAndSetRestoreWindow() { 287 void WindowSelector::RemoveFocusAndSetRestoreWindow() {
245 aura::client::FocusClient* focus_client = aura::client::GetFocusClient( 288 aura::client::FocusClient* focus_client = aura::client::GetFocusClient(
246 Shell::GetPrimaryRootWindow()); 289 Shell::GetPrimaryRootWindow());
247 DCHECK(!restore_focus_window_); 290 DCHECK(!restore_focus_window_);
248 restore_focus_window_ = focus_client->GetFocusedWindow(); 291 restore_focus_window_ = focus_client->GetFocusedWindow();
249 if (restore_focus_window_) { 292 if (restore_focus_window_) {
250 focus_client->FocusWindow(NULL); 293 focus_client->FocusWindow(NULL);
251 restore_focus_window_->AddObserver(this); 294 if (observed_windows_.find(restore_focus_window_) ==
295 observed_windows_.end()) {
296 restore_focus_window_->AddObserver(this);
297 }
252 } 298 }
253 } 299 }
254 300
255 void WindowSelector::ResetFocusRestoreWindow(bool focus) { 301 void WindowSelector::ResetFocusRestoreWindow(bool focus) {
256 if (!restore_focus_window_) 302 if (!restore_focus_window_)
257 return; 303 return;
258 if (focus) { 304 if (focus) {
259 base::AutoReset<bool> restoring_focus(&restoring_focus_, true); 305 base::AutoReset<bool> restoring_focus(&restoring_focus_, true);
260 restore_focus_window_->Focus(); 306 restore_focus_window_->Focus();
261 } 307 }
262 // If the window is in the windows_ list it needs to continue to be observed. 308 // If the window is in the observed_windows_ list it needs to continue to be
263 if (std::find_if(windows_.begin(), windows_.end(), 309 // observed.
264 WindowSelectorWindowComparator(restore_focus_window_)) == 310 if (observed_windows_.find(restore_focus_window_) ==
265 windows_.end()) { 311 observed_windows_.end()) {
266 restore_focus_window_->RemoveObserver(this); 312 restore_focus_window_->RemoveObserver(this);
267 } 313 }
268 restore_focus_window_ = NULL; 314 restore_focus_window_ = NULL;
269 } 315 }
270 316
271 } // namespace ash 317 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/overview/window_selector.h ('k') | ash/wm/overview/window_selector_item.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698