Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <functional> | 8 #include <functional> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "ash/accessibility_delegate.h" | 12 #include "ash/accessibility_delegate.h" |
| 13 #include "ash/ash_switches.h" | 13 #include "ash/ash_switches.h" |
| 14 #include "ash/metrics/user_metrics_recorder.h" | 14 #include "ash/metrics/user_metrics_recorder.h" |
| 15 #include "ash/root_window_controller.h" | 15 #include "ash/root_window_controller.h" |
| 16 #include "ash/shell.h" | 16 #include "ash/shell.h" |
| 17 #include "ash/shell_window_ids.h" | 17 #include "ash/shell_window_ids.h" |
| 18 #include "ash/switchable_windows.h" | 18 #include "ash/switchable_windows.h" |
| 19 #include "ash/wm/overview/scoped_overview_animation_settings.h" | |
| 20 #include "ash/wm/overview/scoped_transform_overview_window.h" | |
| 21 #include "ash/wm/overview/window_grid.h" | 19 #include "ash/wm/overview/window_grid.h" |
| 22 #include "ash/wm/overview/window_selector_delegate.h" | 20 #include "ash/wm/overview/window_selector_delegate.h" |
| 23 #include "ash/wm/overview/window_selector_item.h" | 21 #include "ash/wm/overview/window_selector_item.h" |
| 24 #include "ash/wm/panels/panel_layout_manager.h" | 22 #include "ash/wm/panels/panel_layout_manager.h" |
| 25 #include "ash/wm/window_state.h" | 23 #include "ash/wm/window_state.h" |
| 26 #include "base/auto_reset.h" | 24 #include "base/auto_reset.h" |
| 27 #include "base/command_line.h" | 25 #include "base/command_line.h" |
| 28 #include "base/metrics/histogram.h" | 26 #include "base/metrics/histogram.h" |
| 29 #include "third_party/skia/include/core/SkPaint.h" | 27 #include "third_party/skia/include/core/SkPaint.h" |
| 30 #include "third_party/skia/include/core/SkPath.h" | 28 #include "third_party/skia/include/core/SkPath.h" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 textfield->RequestFocus(); | 209 textfield->RequestFocus(); |
| 212 | 210 |
| 213 return widget; | 211 return widget; |
| 214 } | 212 } |
| 215 | 213 |
| 216 } // namespace | 214 } // namespace |
| 217 | 215 |
| 218 const int WindowSelector::kTextFilterBottomEdge = | 216 const int WindowSelector::kTextFilterBottomEdge = |
| 219 kTextFilterDistanceFromTop + kTextFilterHeight; | 217 kTextFilterDistanceFromTop + kTextFilterHeight; |
| 220 | 218 |
| 219 // static | |
| 220 bool WindowSelector::IsSelectable(aura::Window* window) { | |
| 221 wm::WindowState* state = wm::GetWindowState(window); | |
| 222 if (state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED || | |
| 223 state->GetStateType() == wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED) | |
|
varkha
2015/04/07 21:45:45
nit: Multi-line condition needs {
oshima
2015/04/07 22:15:03
Done.
| |
| 224 return false; | |
|
varkha
2015/04/07 21:45:45
Just a question: Are you considering to make docke
flackr
2015/04/07 21:48:28
Yes, we should be - http://crbug.com/351329. It wi
| |
| 225 return window->type() == ui::wm::WINDOW_TYPE_NORMAL || | |
| 226 window->type() == ui::wm::WINDOW_TYPE_PANEL; | |
| 227 } | |
| 228 | |
| 221 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) | 229 WindowSelector::WindowSelector(WindowSelectorDelegate* delegate) |
| 222 : delegate_(delegate), | 230 : delegate_(delegate), |
| 223 restore_focus_window_(aura::client::GetFocusClient( | 231 restore_focus_window_(aura::client::GetFocusClient( |
| 224 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), | 232 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), |
| 225 ignore_activations_(false), | 233 ignore_activations_(false), |
| 226 selected_grid_index_(0), | 234 selected_grid_index_(0), |
| 227 overview_start_time_(base::Time::Now()), | 235 overview_start_time_(base::Time::Now()), |
| 228 num_key_presses_(0), | 236 num_key_presses_(0), |
| 229 num_items_(0), | 237 num_items_(0), |
| 230 showing_selection_widget_(false), | 238 showing_selection_widget_(false), |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 | 303 |
| 296 DCHECK(!grid_list_.empty()); | 304 DCHECK(!grid_list_.empty()); |
| 297 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); | 305 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.Items", num_items_); |
| 298 | 306 |
| 299 Shell* shell = Shell::GetInstance(); | 307 Shell* shell = Shell::GetInstance(); |
| 300 | 308 |
| 301 shell->activation_client()->AddObserver(this); | 309 shell->activation_client()->AddObserver(this); |
| 302 | 310 |
| 303 shell->GetScreen()->AddObserver(this); | 311 shell->GetScreen()->AddObserver(this); |
| 304 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); | 312 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); |
| 305 HideAndTrackNonOverviewWindows(); | |
| 306 // Send an a11y alert. | 313 // Send an a11y alert. |
| 307 shell->accessibility_delegate()->TriggerAccessibilityAlert( | 314 shell->accessibility_delegate()->TriggerAccessibilityAlert( |
| 308 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 315 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 309 | 316 |
| 310 UpdateShelfVisibility(); | 317 UpdateShelfVisibility(); |
| 311 } | 318 } |
| 312 | 319 |
| 313 // NOTE: The work done in Shutdown() is not done in the destructor because it | 320 // NOTE: The work done in Shutdown() is not done in the destructor because it |
| 314 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect | 321 // may cause other, unrelated classes, (ie PanelLayoutManager) to make indirect |
| 315 // calls to restoring_minimized_windows() on a partially destructed object. | 322 // calls to restoring_minimized_windows() on a partially destructed object. |
| 316 void WindowSelector::Shutdown() { | 323 void WindowSelector::Shutdown() { |
| 317 ResetFocusRestoreWindow(true); | 324 ResetFocusRestoreWindow(true); |
| 318 RemoveAllObservers(); | 325 RemoveAllObservers(); |
| 319 | 326 |
| 320 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 327 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 321 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); | 328 for (aura::Window::Windows::const_iterator iter = root_windows.begin(); |
| 322 iter != root_windows.end(); iter++) { | 329 iter != root_windows.end(); iter++) { |
| 323 // Un-hide the callout widgets for panels. It is safe to call this for | 330 // Un-hide the callout widgets for panels. It is safe to call this for |
| 324 // root_windows that don't contain any panel windows. | 331 // root_windows that don't contain any panel windows. |
| 325 static_cast<PanelLayoutManager*>( | 332 static_cast<PanelLayoutManager*>( |
| 326 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) | 333 Shell::GetContainer(*iter, kShellWindowId_PanelContainer) |
| 327 ->layout_manager())->SetShowCalloutWidgets(true); | 334 ->layout_manager())->SetShowCalloutWidgets(true); |
| 328 } | 335 } |
| 329 | 336 |
| 330 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows()); | |
| 331 for (aura::WindowTracker::Windows::const_iterator iter = | |
| 332 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { | |
| 333 ScopedOverviewAnimationSettings animation_settings( | |
| 334 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | |
| 335 *iter); | |
| 336 (*iter)->layer()->SetOpacity(1); | |
| 337 (*iter)->Show(); | |
| 338 } | |
| 339 | |
| 340 size_t remaining_items = 0; | 337 size_t remaining_items = 0; |
| 341 for (WindowGrid* window_grid : grid_list_) { | 338 for (WindowGrid* window_grid : grid_list_) { |
| 342 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) | 339 for (WindowSelectorItem* window_selector_item : window_grid->window_list()) |
| 343 window_selector_item->RestoreWindow(); | 340 window_selector_item->RestoreWindow(); |
| 344 remaining_items += window_grid->size(); | 341 remaining_items += window_grid->size(); |
| 345 } | 342 } |
| 346 | 343 |
| 347 DCHECK(num_items_ >= remaining_items); | 344 DCHECK(num_items_ >= remaining_items); |
| 348 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", | 345 UMA_HISTOGRAM_COUNTS_100("Ash.WindowSelector.OverviewClosedItems", |
| 349 num_items_ - remaining_items); | 346 num_items_ - remaining_items); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 // TODO(flackr): Keep window selection active on remaining displays. | 446 // TODO(flackr): Keep window selection active on remaining displays. |
| 450 CancelSelection(); | 447 CancelSelection(); |
| 451 } | 448 } |
| 452 | 449 |
| 453 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display, | 450 void WindowSelector::OnDisplayMetricsChanged(const gfx::Display& display, |
| 454 uint32_t metrics) { | 451 uint32_t metrics) { |
| 455 PositionWindows(/* animate */ false); | 452 PositionWindows(/* animate */ false); |
| 456 } | 453 } |
| 457 | 454 |
| 458 void WindowSelector::OnWindowAdded(aura::Window* new_window) { | 455 void WindowSelector::OnWindowAdded(aura::Window* new_window) { |
| 459 if (new_window->type() != ui::wm::WINDOW_TYPE_NORMAL && | 456 if (!IsSelectable(new_window)) |
| 460 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) { | |
| 461 return; | 457 return; |
| 462 } | |
| 463 | 458 |
| 464 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 459 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| 465 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && | 460 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && |
| 466 !::wm::GetTransientParent(new_window)) { | 461 !::wm::GetTransientParent(new_window)) { |
| 467 // The new window is in one of the switchable containers, abort overview. | 462 // The new window is in one of the switchable containers, abort overview. |
| 468 CancelSelection(); | 463 CancelSelection(); |
| 469 return; | 464 return; |
| 470 } | 465 } |
| 471 } | 466 } |
| 472 } | 467 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 Move(WindowSelector::RIGHT, false); | 544 Move(WindowSelector::RIGHT, false); |
| 550 } | 545 } |
| 551 | 546 |
| 552 void WindowSelector::PositionWindows(bool animate) { | 547 void WindowSelector::PositionWindows(bool animate) { |
| 553 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); | 548 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); |
| 554 iter != grid_list_.end(); iter++) { | 549 iter != grid_list_.end(); iter++) { |
| 555 (*iter)->PositionWindows(animate); | 550 (*iter)->PositionWindows(animate); |
| 556 } | 551 } |
| 557 } | 552 } |
| 558 | 553 |
| 559 void WindowSelector::HideAndTrackNonOverviewWindows() { | |
| 560 // Add the windows to hidden_windows first so that if any are destroyed | |
| 561 // while hiding them they are tracked. | |
| 562 for (ScopedVector<WindowGrid>::iterator grid_iter = grid_list_.begin(); | |
| 563 grid_iter != grid_list_.end(); ++grid_iter) { | |
| 564 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | |
| 565 const aura::Window* container = | |
| 566 Shell::GetContainer((*grid_iter)->root_window(), | |
| 567 kSwitchableWindowContainerIds[i]); | |
| 568 for (aura::Window::Windows::const_iterator iter = | |
| 569 container->children().begin(); iter != container->children().end(); | |
| 570 ++iter) { | |
| 571 if (!(*iter)->IsVisible() || (*grid_iter)->Contains(*iter)) | |
| 572 continue; | |
| 573 hidden_windows_.Add(*iter); | |
| 574 } | |
| 575 } | |
| 576 } | |
| 577 | |
| 578 // Copy the window list as it can change during iteration. | |
| 579 const aura::WindowTracker::Windows hidden_windows(hidden_windows_.windows()); | |
| 580 for (aura::WindowTracker::Windows::const_iterator iter = | |
| 581 hidden_windows.begin(); iter != hidden_windows.end(); ++iter) { | |
| 582 if (!hidden_windows_.Contains(*iter)) | |
| 583 continue; | |
| 584 ScopedOverviewAnimationSettings animation_settings( | |
| 585 OverviewAnimationType::OVERVIEW_ANIMATION_HIDE_WINDOW, | |
| 586 *iter); | |
| 587 (*iter)->Hide(); | |
| 588 // Hiding the window can result in it being destroyed. | |
| 589 if (!hidden_windows_.Contains(*iter)) | |
| 590 continue; | |
| 591 (*iter)->layer()->SetOpacity(0); | |
| 592 } | |
| 593 } | |
| 594 | |
| 595 void WindowSelector::ResetFocusRestoreWindow(bool focus) { | 554 void WindowSelector::ResetFocusRestoreWindow(bool focus) { |
| 596 if (!restore_focus_window_) | 555 if (!restore_focus_window_) |
| 597 return; | 556 return; |
| 598 if (focus) { | 557 if (focus) { |
| 599 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); | 558 base::AutoReset<bool> restoring_focus(&ignore_activations_, true); |
| 600 restore_focus_window_->Focus(); | 559 restore_focus_window_->Focus(); |
| 601 } | 560 } |
| 602 // If the window is in the observed_windows_ list it needs to continue to be | 561 // If the window is in the observed_windows_ list it needs to continue to be |
| 603 // observed. | 562 // observed. |
| 604 if (observed_windows_.find(restore_focus_window_) == | 563 if (observed_windows_.find(restore_focus_window_) == |
| 605 observed_windows_.end()) { | 564 observed_windows_.end()) { |
| 606 restore_focus_window_->RemoveObserver(this); | 565 restore_focus_window_->RemoveObserver(this); |
| 607 } | 566 } |
| 608 restore_focus_window_ = nullptr; | 567 restore_focus_window_ = nullptr; |
| 609 } | 568 } |
| 610 | 569 |
| 611 void WindowSelector::Move(Direction direction, bool animate) { | 570 void WindowSelector::Move(Direction direction, bool animate) { |
| 612 // Keep calling Move() on the grids until one of them reports no overflow or | 571 // Keep calling Move() on the grids until one of them reports no overflow or |
| 613 // we made a full cycle on all the grids. | 572 // we made a full cycle on all the grids. |
| 614 for (size_t i = 0; | 573 for (size_t i = 0; |
| 615 i <= grid_list_.size() && | 574 i <= grid_list_.size() && |
| 616 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { | 575 grid_list_[selected_grid_index_]->Move(direction, animate); i++) { |
| 617 // TODO(flackr): If there are more than two monitors, move between grids | 576 // TODO(flackr): If there are more than two monitors, move between grids |
| 618 // in the requested direction. | 577 // in the requested direction. |
| 619 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); | 578 selected_grid_index_ = (selected_grid_index_ + 1) % grid_list_.size(); |
| 620 } | 579 } |
| 621 } | 580 } |
| 622 | 581 |
| 623 } // namespace ash | 582 } // namespace ash |
| OLD | NEW |