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

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

Issue 844763006: Change overview mode to so that docked panel windows are not grouped together. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changed OnOverviewModeEnding to OnOverviewModeEnded. Created 5 years, 11 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
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 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 }; 85 };
86 86
87 // A comparator for locating a selectable window given a targeted window. 87 // A comparator for locating a selectable window given a targeted window.
88 struct WindowSelectorItemTargetComparator 88 struct WindowSelectorItemTargetComparator
89 : public std::unary_function<WindowSelectorItem*, bool> { 89 : public std::unary_function<WindowSelectorItem*, bool> {
90 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) 90 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window)
91 : target(target_window) { 91 : target(target_window) {
92 } 92 }
93 93
94 bool operator()(WindowSelectorItem* window) const { 94 bool operator()(WindowSelectorItem* window) const {
95 return window->Contains(target); 95 return window->GetWindow() == target;
96 } 96 }
97 97
98 const aura::Window* target; 98 const aura::Window* target;
99 }; 99 };
100 100
101 // A comparator for locating a selector item for a given root. 101 // A comparator for locating a selector item for a given root.
102 struct WindowSelectorItemForRoot 102 struct WindowSelectorItemForRoot
103 : public std::unary_function<WindowSelectorItem*, bool> { 103 : public std::unary_function<WindowSelectorItem*, bool> {
104 explicit WindowSelectorItemForRoot(const aura::Window* root) 104 explicit WindowSelectorItemForRoot(const aura::Window* root)
105 : root_window(root) { 105 : root_window(root) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 textfield->RequestFocus(); 210 textfield->RequestFocus();
211 211
212 return widget; 212 return widget;
213 } 213 }
214 214
215 } // namespace 215 } // namespace
216 216
217 const int WindowSelector::kTextFilterBottomEdge = 217 const int WindowSelector::kTextFilterBottomEdge =
218 kTextFilterDistanceFromTop + kTextFilterHeight; 218 kTextFilterDistanceFromTop + kTextFilterHeight;
219 219
220 WindowSelector::WindowSelector(const WindowList& windows, 220 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate)
221 WindowSelectorDelegate* delegate)
222 : delegate_(delegate), 221 : delegate_(delegate),
223 restore_focus_window_(aura::client::GetFocusClient( 222 restore_focus_window_(aura::client::GetFocusClient(
224 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), 223 Shell::GetPrimaryRootWindow())->GetFocusedWindow()),
225 ignore_activations_(false), 224 ignore_activations_(false),
226 selected_grid_index_(0), 225 selected_grid_index_(0),
227 overview_start_time_(base::Time::Now()), 226 overview_start_time_(base::Time::Now()),
228 num_key_presses_(0), 227 num_key_presses_(0),
229 num_items_(0), 228 num_items_(0),
230 showing_selection_widget_(false), 229 showing_selection_widget_(false),
231 text_filter_string_length_(0), 230 text_filter_string_length_(0),
232 num_times_textfield_cleared_(0) { 231 num_times_textfield_cleared_(0),
232 restoring_minimized_windows_(false) {
233 DCHECK(delegate_); 233 DCHECK(delegate_);
234 Shell* shell = Shell::GetInstance(); 234 }
235 shell->OnOverviewModeStarting();
236 235
236 WindowSelector::~WindowSelector() {
237 RemoveAllObservers();
238 }
239
240 // NOTE: The work done in Init() is not done in the constructor because it may
241 // cause other, unrelated classes, (ie PanelLayoutManager) to make indirect
242 // calls to restoring_minimized_windows() on a partially constructed object.
243 void WindowSelector::Init(const WindowList& windows) {
237 if (restore_focus_window_) 244 if (restore_focus_window_)
238 restore_focus_window_->AddObserver(this); 245 restore_focus_window_->AddObserver(this);
239 246
240 const aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 247 const aura::Window::Windows root_windows = Shell::GetAllRootWindows();
241 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 248 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
242 iter != root_windows.end(); iter++) { 249 iter != root_windows.end(); iter++) {
243 // Observed switchable containers for newly created windows on all root 250 // Observed switchable containers for newly created windows on all root
244 // windows. 251 // windows.
245 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { 252 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) {
246 aura::Window* container = Shell::GetContainer(*iter, 253 aura::Window* container = Shell::GetContainer(*iter,
247 kSwitchableWindowContainerIds[i]); 254 kSwitchableWindowContainerIds[i]);
248 container->AddObserver(this); 255 container->AddObserver(this);
249 observed_windows_.insert(container); 256 observed_windows_.insert(container);
250 } 257 }
251 258
252 // Hide the callout widgets for panels. It is safe to call this for 259 // Hide the callout widgets for panels. It is safe to call this for
253 // root windows that don't contain any panel windows. 260 // root windows that don't contain any panel windows.
254 static_cast<PanelLayoutManager*>( 261 static_cast<PanelLayoutManager*>(
255 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) 262 Shell::GetContainer(*iter, kShellWindowId_PanelContainer)
256 ->layout_manager())->SetShowCalloutWidgets(false); 263 ->layout_manager())->SetShowCalloutWidgets(false);
257 264
258 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this)); 265 scoped_ptr<WindowGrid> grid(new WindowGrid(*iter, windows, this));
259 if (grid->empty()) 266 if (grid->empty())
260 continue; 267 continue;
261 num_items_ += grid->size(); 268 num_items_ += grid->size();
262 grid_list_.push_back(grid.release()); 269 grid_list_.push_back(grid.release());
263 } 270 }
264 271
265 // Do not call PrepareForOverview until all items are added to window_list_ as 272 {
266 // we don't want to cause any window updates until all windows in overview 273 // The calls to WindowGrid::PrepareForOverview() and CreateTextFilter(...)
267 // are observed. See http://crbug.com/384495. 274 // requires some LayoutManagers (ie PanelLayoutManager) to perform layouts
268 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); 275 // so that windows are correctly visible and properly animated in overview
269 iter != grid_list_.end(); ++iter) { 276 // mode. Otherwise these layouts should be suppressed during overview mode
270 (*iter)->PrepareForOverview(); 277 // so they don't conflict with overview mode animations. The
271 (*iter)->PositionWindows(true); 278 // |restoring_minimized_windows_| flag enables the PanelLayoutManager to
279 // make this decision.
280 base::AutoReset<bool> auto_restoring_minimized_windows(
281 &restoring_minimized_windows_, true);
282
283 // Do not call PrepareForOverview until all items are added to window_list_
284 // as we don't want to cause any window updates until all windows in
285 // overview are observed. See http://crbug.com/384495.
286 for (auto window_grid : grid_list_) {
287 window_grid->PrepareForOverview();
288 window_grid->PositionWindows(true);
289 }
290
291 text_filter_widget_.reset(
292 CreateTextFilter(this, Shell::GetPrimaryRootWindow()));
272 } 293 }
273 294
274 DCHECK(!grid_list_.empty()); 295 DCHECK(!grid_list_.empty());
275 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); 296 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_);
276 297
277 text_filter_widget_.reset( 298 Shell* shell = Shell::GetInstance();
278 CreateTextFilter(this, Shell::GetPrimaryRootWindow()));
279 299
280 shell->activation_client()->AddObserver(this); 300 shell->activation_client()->AddObserver(this);
281 301
282 shell->GetScreen()->AddObserver(this); 302 shell->GetScreen()->AddObserver(this);
283 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); 303 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW);
284 HideAndTrackNonOverviewWindows(); 304 HideAndTrackNonOverviewWindows();
285 // Send an a11y alert. 305 // Send an a11y alert.
286 shell->accessibility_delegate()->TriggerAccessibilityAlert( 306 shell->accessibility_delegate()->TriggerAccessibilityAlert(
287 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); 307 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
288 308
289 UpdateShelfVisibility(); 309 UpdateShelfVisibility();
290 } 310 }
291 311
292 WindowSelector::~WindowSelector() { 312 // NOTE: The work done in Shutdown() is not done in the destructor because it
293 Shell* shell = Shell::GetInstance(); 313 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect
294 314 // calls to restoring_minimized_windows() on a partially destructed object.
315 void WindowSelector::Shutdown() {
295 ResetFocusRestoreWindow(true); 316 ResetFocusRestoreWindow(true);
296 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin(); 317 RemoveAllObservers();
297 iter != observed_windows_.end(); ++iter) {
298 (*iter)->RemoveObserver(this);
299 }
300 shell->activation_client()->RemoveObserver(this);
301 318
302 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 319 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
303 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); 320 for (aura::Window::Windows::const_iterator iter = root_windows.begin();
304 iter != root_windows.end(); iter++) { 321 iter != root_windows.end(); iter++) {
305 // Un-hide the callout widgets for panels. It is safe to call this for 322 // Un-hide the callout widgets for panels. It is safe to call this for
306 // root_windows that don't contain any panel windows. 323 // root_windows that don't contain any panel windows.
307 static_cast<PanelLayoutManager*>( 324 static_cast<PanelLayoutManager*>(
308 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) 325 Shell::GetContainer(*iter, kShellWindowId_PanelContainer)
309 ->layout_manager())->SetShowCalloutWidgets(true); 326 ->layout_manager())->SetShowCalloutWidgets(true);
310 } 327 }
311 328
312 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows()); 329 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows());
313 for (aura::WindowTracker::Windows::const_iterator iter = 330 for (aura::WindowTracker::Windows::const_iterator iter =
314 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { 331 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) {
315 ScopedOverviewAnimationSettings animation_settings( 332 ScopedOverviewAnimationSettings animation_settings(
316 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, 333 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS,
317 *iter); 334 *iter);
318 (*iter)->layer()->SetOpacity(1); 335 (*iter)->layer()->SetOpacity(1);
319 (*iter)->Show(); 336 (*iter)->Show();
320 } 337 }
321 338
322 shell->GetScreen()->RemoveObserver(this);
323
324 size_t remaining_items = 0; 339 size_t remaining_items = 0;
325 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); 340 for (auto window_grid : grid_list_) {
326 iter != grid_list_.end(); iter++) { 341 for (auto window_selector_item : window_grid->window_list())
327 remaining_items += (*iter)->size(); 342 window_selector_item->RestoreWindow();
343 remaining_items += window_grid->size();
328 } 344 }
329 345
330 DCHECK(num_items_ >= remaining_items); 346 DCHECK(num_items_ >= remaining_items);
331 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", 347 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems",
332 num_items_ - remaining_items); 348 num_items_ - remaining_items);
333 UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowSelector.TimeInOverview", 349 UMA_HISTOGRAM_MEDIUM_TIMES("Ash.WindowSelector.TimeInOverview",
334 base::Time::Now() - overview_start_time_); 350 base::Time::Now() - overview_start_time_);
335 351
336 // Record metrics related to text filtering. 352 // Record metrics related to text filtering.
337 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringStringLength", 353 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringStringLength",
338 text_filter_string_length_); 354 text_filter_string_length_);
339 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringTextfieldCleared", 355 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.TextFilteringTextfieldCleared",
340 num_times_textfield_cleared_); 356 num_times_textfield_cleared_);
341 if (text_filter_string_length_) { 357 if (text_filter_string_length_) {
342 UMA_HISTOGRAM_MEDIUM_TIMES( 358 UMA_HISTOGRAM_MEDIUM_TIMES(
343 "Ash.WindowSelector.TimeInOverviewWithTextFiltering", 359 "Ash.WindowSelector.TimeInOverviewWithTextFiltering",
344 base::Time::Now() - overview_start_time_); 360 base::Time::Now() - overview_start_time_);
345 UMA_HISTOGRAM_COUNTS_100( 361 UMA_HISTOGRAM_COUNTS_100(
346 "Ash.WindowSelector.ItemsWhenTextFilteringUsed", 362 "Ash.WindowSelector.ItemsWhenTextFilteringUsed",
347 remaining_items); 363 remaining_items);
348 } 364 }
349 365
350 // TODO(flackr): Change this to OnOverviewModeEnded and move it to when
351 // everything is done.
352 shell->OnOverviewModeEnding();
353
354 // Clearing the window list resets the ignored_by_shelf flag on the windows. 366 // Clearing the window list resets the ignored_by_shelf flag on the windows.
355 grid_list_.clear(); 367 grid_list_.clear();
356 UpdateShelfVisibility(); 368 UpdateShelfVisibility();
357 } 369 }
358 370
371 void WindowSelector::RemoveAllObservers() {
372 Shell* shell = Shell::GetInstance();
373 for (std::set<aura::Window*>::iterator iter = observed_windows_.begin();
jonross 2015/01/16 20:10:20 for(auto)
bruthig 2015/01/16 20:22:46 Done.
374 iter != observed_windows_.end(); ++iter) {
375 (*iter)->RemoveObserver(this);
376 }
377 shell->activation_client()->RemoveObserver(this);
378 shell->GetScreen()->RemoveObserver(this);
379 if (restore_focus_window_)
380 restore_focus_window_->RemoveObserver(this);
381 }
382
359 void WindowSelector::CancelSelection() { 383 void WindowSelector::CancelSelection() {
360 delegate_->OnSelectionEnded(); 384 delegate_->OnSelectionEnded();
361 } 385 }
362 386
363 void WindowSelector::OnGridEmpty(WindowGrid* grid) { 387 void WindowSelector::OnGridEmpty(WindowGrid* grid) {
364 ScopedVector<WindowGrid>::iterator iter = 388 ScopedVector<WindowGrid>::iterator iter =
365 std::find(grid_list_.begin(), grid_list_.end(), grid); 389 std::find(grid_list_.begin(), grid_list_.end(), grid);
366 DCHECK(iter != grid_list_.end()); 390 DCHECK(iter != grid_list_.end());
367 grid_list_.erase(iter); 391 grid_list_.erase(iter);
368 // TODO(flackr): Use the previous index for more than two displays. 392 // TODO(flackr): Use the previous index for more than two displays.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 if (!grid_list_[selected_grid_index_]->is_selecting()) 426 if (!grid_list_[selected_grid_index_]->is_selecting())
403 return false; 427 return false;
404 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses", 428 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.ArrowKeyPresses",
405 num_key_presses_); 429 num_key_presses_);
406 UMA_HISTOGRAM_CUSTOM_COUNTS( 430 UMA_HISTOGRAM_CUSTOM_COUNTS(
407 "Ash.WindowSelector.KeyPressesOverItemsRatio", 431 "Ash.WindowSelector.KeyPressesOverItemsRatio",
408 (num_key_presses_ * 100) / num_items_, 1, 300, 30); 432 (num_key_presses_ * 100) / num_items_, 1, 300, 30);
409 Shell::GetInstance()->metrics()->RecordUserMetricsAction( 433 Shell::GetInstance()->metrics()->RecordUserMetricsAction(
410 UMA_WINDOW_OVERVIEW_ENTER_KEY); 434 UMA_WINDOW_OVERVIEW_ENTER_KEY);
411 wm::GetWindowState(grid_list_[selected_grid_index_]-> 435 wm::GetWindowState(grid_list_[selected_grid_index_]->
412 SelectedWindow()->SelectionWindow())->Activate(); 436 SelectedWindow()->GetWindow())->Activate();
413 break; 437 break;
414 default: 438 default:
415 // Not a key we are interested in, allow the textfield to handle it. 439 // Not a key we are interested in, allow the textfield to handle it.
416 return false; 440 return false;
417 } 441 }
418 return true; 442 return true;
419 } 443 }
420 444
421 void WindowSelector::OnDisplayAdded(const gfx::Display& display) { 445 void WindowSelector::OnDisplayAdded(const gfx::Display& display) {
422 } 446 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 RootWindowGridComparator(gained_active->GetRootWindow())); 491 RootWindowGridComparator(gained_active->GetRootWindow()));
468 if (grid == grid_list_.end()) 492 if (grid == grid_list_.end())
469 return; 493 return;
470 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list(); 494 const std::vector<WindowSelectorItem*> windows = (*grid)->window_list();
471 495
472 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if( 496 ScopedVector<WindowSelectorItem>::const_iterator iter = std::find_if(
473 windows.begin(), windows.end(), 497 windows.begin(), windows.end(),
474 WindowSelectorItemTargetComparator(gained_active)); 498 WindowSelectorItemTargetComparator(gained_active));
475 499
476 if (iter != windows.end()) 500 if (iter != windows.end())
477 (*iter)->RestoreWindowOnExit(gained_active); 501 (*iter)->ShowWindowOnExit();
478 502
479 // Don't restore focus on exit if a window was just activated. 503 // Don't restore focus on exit if a window was just activated.
480 ResetFocusRestoreWindow(false); 504 ResetFocusRestoreWindow(false);
481 CancelSelection(); 505 CancelSelection();
482 } 506 }
483 507
484 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active, 508 void WindowSelector::OnAttemptToReactivateWindow(aura::Window* request_active,
485 aura::Window* actual_active) { 509 aura::Window* actual_active) {
486 OnWindowActivated(request_active, actual_active); 510 OnWindowActivated(request_active, actual_active);
487 } 511 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 for (size_t i = 0; 619 for (size_t i = 0;
596 i <= grid_list_.size() && 620 i <= grid_list_.size() &&
597 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { 621 grid_list_[selected_grid_index_]->Move(direction, animate); i++) {
598 // TODO(flackr): If there are more than two monitors, move between grids 622 // TODO(flackr): If there are more than two monitors, move between grids
599 // in the requested direction. 623 // in the requested direction.
600 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); 624 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size();
601 } 625 }
602 } 626 }
603 627
604 } // namespace ash 628 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698