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 |