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 | 8 |
| 9 #include "ash/accessibility_delegate.h" | 9 #include "ash/accessibility_delegate.h" |
| 10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
| 11 #include "ash/metrics/user_metrics_recorder.h" | 11 #include "ash/metrics/user_metrics_recorder.h" |
| 12 #include "ash/root_window_controller.h" | 12 #include "ash/root_window_controller.h" |
| 13 #include "ash/screen_util.h" | |
| 14 #include "ash/shell.h" | 13 #include "ash/shell.h" |
| 15 #include "ash/shell_window_ids.h" | 14 #include "ash/shell_window_ids.h" |
| 16 #include "ash/switchable_windows.h" | 15 #include "ash/switchable_windows.h" |
| 17 #include "ash/wm/overview/scoped_transform_overview_window.h" | 16 #include "ash/wm/overview/scoped_transform_overview_window.h" |
| 17 #include "ash/wm/overview/window_grid.h" | |
| 18 #include "ash/wm/overview/window_selector_delegate.h" | 18 #include "ash/wm/overview/window_selector_delegate.h" |
| 19 #include "ash/wm/overview/window_selector_item.h" | 19 #include "ash/wm/overview/window_selector_item.h" |
| 20 #include "ash/wm/overview/window_selector_panels.h" | 20 #include "ash/wm/overview/window_selector_panels.h" |
| 21 #include "ash/wm/overview/window_selector_window.h" | 21 #include "ash/wm/overview/window_selector_window.h" |
| 22 #include "ash/wm/window_state.h" | 22 #include "ash/wm/window_state.h" |
| 23 #include "base/auto_reset.h" | 23 #include "base/auto_reset.h" |
| 24 #include "base/command_line.h" | 24 #include "base/command_line.h" |
| 25 #include "base/metrics/histogram.h" | 25 #include "base/metrics/histogram.h" |
| 26 #include "base/strings/string_number_conversions.h" | 26 #include "base/strings/string_number_conversions.h" |
| 27 #include "third_party/skia/include/core/SkColor.h" | 27 #include "third_party/skia/include/core/SkColor.h" |
| 28 #include "ui/aura/client/cursor_client.h" | 28 #include "ui/aura/client/cursor_client.h" |
| 29 #include "ui/aura/client/focus_client.h" | 29 #include "ui/aura/client/focus_client.h" |
| 30 #include "ui/aura/window.h" | 30 #include "ui/aura/window.h" |
| 31 #include "ui/aura/window_event_dispatcher.h" | 31 #include "ui/aura/window_event_dispatcher.h" |
| 32 #include "ui/aura/window_observer.h" | 32 #include "ui/aura/window_observer.h" |
| 33 #include "ui/compositor/layer_animation_observer.h" | |
| 34 #include "ui/compositor/scoped_layer_animation_settings.h" | 33 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 35 #include "ui/events/event.h" | 34 #include "ui/events/event.h" |
| 36 #include "ui/gfx/screen.h" | 35 #include "ui/gfx/screen.h" |
| 37 #include "ui/views/background.h" | 36 #include "ui/views/background.h" |
| 38 #include "ui/views/widget/widget.h" | 37 #include "ui/views/widget/widget.h" |
| 39 #include "ui/wm/core/window_util.h" | 38 #include "ui/wm/core/window_util.h" |
| 40 #include "ui/wm/public/activation_client.h" | 39 #include "ui/wm/public/activation_client.h" |
| 41 | 40 |
| 42 namespace ash { | 41 namespace ash { |
| 43 | 42 |
| 44 namespace { | 43 namespace { |
| 45 | 44 |
| 46 // Conceptually the window overview is a table or grid of cells having this | |
| 47 // fixed aspect ratio. The number of columns is determined by maximizing the | |
| 48 // area of them based on the number of windows. | |
| 49 const float kCardAspectRatio = 4.0f / 3.0f; | |
| 50 | |
| 51 // In the conceptual overview table, the window margin is the space reserved | |
| 52 // around the window within the cell. This margin does not overlap so the | |
| 53 // closest distance between adjacent windows will be twice this amount. | |
| 54 const int kWindowMargin = 30; | |
| 55 | |
| 56 // The minimum number of cards along the major axis (i.e. horizontally on a | |
| 57 // landscape orientation). | |
| 58 const int kMinCardsMajor = 3; | |
| 59 | |
| 60 // A comparator for locating a given target window. | |
| 61 struct WindowSelectorItemComparator | |
| 62 : public std::unary_function<WindowSelectorItem*, bool> { | |
| 63 explicit WindowSelectorItemComparator(const aura::Window* target_window) | |
| 64 : target(target_window) { | |
| 65 } | |
| 66 | |
| 67 bool operator()(WindowSelectorItem* window) const { | |
| 68 return window->HasSelectableWindow(target); | |
| 69 } | |
| 70 | |
| 71 const aura::Window* target; | |
| 72 }; | |
| 73 | |
| 74 // An observer which holds onto the passed widget until the animation is | |
| 75 // complete. | |
| 76 class CleanupWidgetAfterAnimationObserver : public ui::LayerAnimationObserver { | |
| 77 public: | |
| 78 explicit CleanupWidgetAfterAnimationObserver( | |
| 79 scoped_ptr<views::Widget> widget); | |
| 80 | |
| 81 // ui::LayerAnimationObserver: | |
| 82 virtual void OnLayerAnimationEnded( | |
| 83 ui::LayerAnimationSequence* sequence) OVERRIDE; | |
| 84 virtual void OnLayerAnimationAborted( | |
| 85 ui::LayerAnimationSequence* sequence) OVERRIDE; | |
| 86 virtual void OnLayerAnimationScheduled( | |
| 87 ui::LayerAnimationSequence* sequence) OVERRIDE; | |
| 88 | |
| 89 private: | |
| 90 virtual ~CleanupWidgetAfterAnimationObserver(); | |
| 91 | |
| 92 scoped_ptr<views::Widget> widget_; | |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(CleanupWidgetAfterAnimationObserver); | |
| 95 }; | |
| 96 | |
| 97 CleanupWidgetAfterAnimationObserver::CleanupWidgetAfterAnimationObserver( | |
| 98 scoped_ptr<views::Widget> widget) | |
| 99 : widget_(widget.Pass()) { | |
| 100 widget_->GetNativeWindow()->layer()->GetAnimator()->AddObserver(this); | |
| 101 } | |
| 102 | |
| 103 CleanupWidgetAfterAnimationObserver::~CleanupWidgetAfterAnimationObserver() { | |
| 104 widget_->GetNativeWindow()->layer()->GetAnimator()->RemoveObserver(this); | |
| 105 } | |
| 106 | |
| 107 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationEnded( | |
| 108 ui::LayerAnimationSequence* sequence) { | |
| 109 delete this; | |
| 110 } | |
| 111 | |
| 112 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationAborted( | |
| 113 ui::LayerAnimationSequence* sequence) { | |
| 114 delete this; | |
| 115 } | |
| 116 | |
| 117 void CleanupWidgetAfterAnimationObserver::OnLayerAnimationScheduled( | |
| 118 ui::LayerAnimationSequence* sequence) { | |
| 119 } | |
| 120 | |
| 121 // A comparator for locating a selectable window given a targeted window. | 45 // A comparator for locating a selectable window given a targeted window. |
| 122 struct WindowSelectorItemTargetComparator | 46 struct WindowSelectorItemTargetComparator |
| 123 : public std::unary_function<WindowSelectorItem*, bool> { | 47 : public std::unary_function<WindowSelectorItem*, bool> { |
| 124 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) | 48 explicit WindowSelectorItemTargetComparator(const aura::Window* target_window) |
| 125 : target(target_window) { | 49 : target(target_window) { |
| 126 } | 50 } |
| 127 | 51 |
| 128 bool operator()(WindowSelectorItem* window) const { | 52 bool operator()(WindowSelectorItem* window) const { |
| 129 return window->TargetedWindow(target) != NULL; | 53 return window->TargetedWindow(target) != NULL; |
| 130 } | 54 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 157 } | 81 } |
| 158 } | 82 } |
| 159 | 83 |
| 160 } // namespace | 84 } // namespace |
| 161 | 85 |
| 162 WindowSelector::WindowSelector(const WindowList& windows, | 86 WindowSelector::WindowSelector(const WindowList& windows, |
| 163 WindowSelectorDelegate* delegate) | 87 WindowSelectorDelegate* delegate) |
| 164 : delegate_(delegate), | 88 : delegate_(delegate), |
| 165 restore_focus_window_(aura::client::GetFocusClient( | 89 restore_focus_window_(aura::client::GetFocusClient( |
| 166 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), | 90 Shell::GetPrimaryRootWindow())->GetFocusedWindow()), |
| 167 ignore_activations_(false) { | 91 ignore_activations_(false), |
| 92 root_index_(0) { | |
| 168 DCHECK(delegate_); | 93 DCHECK(delegate_); |
| 169 | 94 |
| 170 if (restore_focus_window_) | 95 if (restore_focus_window_) |
| 171 restore_focus_window_->AddObserver(this); | 96 restore_focus_window_->AddObserver(this); |
| 172 | 97 |
| 173 std::vector<WindowSelectorPanels*> panels_items; | 98 std::vector<WindowSelectorPanels*> panels_items; |
| 174 for (size_t i = 0; i < windows.size(); ++i) { | 99 for (size_t i = 0; i < windows.size(); ++i) { |
| 175 WindowSelectorItem* item = NULL; | 100 WindowSelectorItem* item = NULL; |
| 176 if (windows[i] != restore_focus_window_) | 101 if (windows[i] != restore_focus_window_) |
| 177 windows[i]->AddObserver(this); | 102 windows[i]->AddObserver(this); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 void WindowSelector::CancelSelection() { | 201 void WindowSelector::CancelSelection() { |
| 277 delegate_->OnSelectionCanceled(); | 202 delegate_->OnSelectionCanceled(); |
| 278 } | 203 } |
| 279 | 204 |
| 280 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) { | 205 void WindowSelector::OnKeyEvent(ui::KeyEvent* event) { |
| 281 if (GetTargetedWindow(static_cast<aura::Window*>(event->target()))) | 206 if (GetTargetedWindow(static_cast<aura::Window*>(event->target()))) |
| 282 event->StopPropagation(); | 207 event->StopPropagation(); |
| 283 if (event->type() != ui::ET_KEY_PRESSED) | 208 if (event->type() != ui::ET_KEY_PRESSED) |
| 284 return; | 209 return; |
| 285 | 210 |
| 286 if (event->key_code() == ui::VKEY_ESCAPE) | 211 // Dummy value so that the compiler does not complain about uninitialized |
|
tdanderson
2014/05/28 16:01:19
Comment not needed.
Nina
2014/05/29 17:12:24
Removed.
| |
| 287 CancelSelection(); | 212 // values. |
| 213 Direction direction = WindowSelector::UP; | |
| 214 bool moving = false; | |
| 215 switch (event->key_code()) { | |
| 216 case ui::VKEY_ESCAPE: | |
| 217 CancelSelection(); | |
| 218 break; | |
| 219 case ui::VKEY_UP: | |
| 220 direction = WindowSelector::UP; | |
|
tdanderson
2014/05/28 16:01:19
Consider defining a private helper with a single p
Nina
2014/05/29 17:12:24
Yep, this is much nicer. Done.
| |
| 221 moving = true; | |
| 222 break; | |
| 223 case ui::VKEY_DOWN: | |
| 224 direction = WindowSelector::DOWN; | |
| 225 moving = true; | |
| 226 break; | |
| 227 case ui::VKEY_RIGHT: | |
| 228 direction = WindowSelector::RIGHT; | |
| 229 moving = true; | |
| 230 break; | |
| 231 case ui::VKEY_LEFT: | |
| 232 direction = WindowSelector::LEFT; | |
| 233 moving = true; | |
| 234 break; | |
| 235 case ui::VKEY_RETURN: | |
| 236 SelectWindow( | |
| 237 grid_list_[root_index_]->SelectedWindow()->SelectionWindow()); | |
| 238 break; | |
| 239 default: | |
| 240 // Not a key we are interested in. | |
| 241 break; | |
| 242 } | |
| 243 if (moving) { | |
|
tdanderson
2014/05/28 16:01:19
It seems you can do a bit of simplification here b
Nina
2014/05/29 17:12:24
Refactoring made this not necessary anymore.
| |
| 244 bool change_root = false; | |
|
tdanderson
2014/05/28 16:01:19
|change_root| is not necessary. Just say if (grid_
Nina
2014/05/29 17:12:24
I thought it was a bit harder to read this way, bu
| |
| 245 change_root = | |
| 246 grid_list_[root_index_]->Move(direction); | |
| 247 if (change_root) { | |
|
tdanderson
2014/05/28 16:01:19
Your documentation for WindowGrid::Move() says tha
Nina
2014/05/29 17:12:24
Modified the comment.
| |
| 248 if (root_index_ >= grid_list_.size() - 1) | |
| 249 root_index_ = 0; | |
| 250 else | |
| 251 root_index_++; | |
| 252 // The grid reported that the movement command corresponds to the next | |
| 253 // root window, call Move() on it to initialize the selection widget. | |
| 254 grid_list_[root_index_]->Move(direction); | |
|
tdanderson
2014/05/28 16:01:19
I don't like the idea of calling Move() for the pu
Nina
2014/05/29 17:12:24
Done.
| |
| 255 } | |
| 256 } | |
| 288 } | 257 } |
| 289 | 258 |
| 290 void WindowSelector::OnMouseEvent(ui::MouseEvent* event) { | 259 void WindowSelector::OnMouseEvent(ui::MouseEvent* event) { |
| 291 aura::Window* target = GetEventTarget(event); | 260 aura::Window* target = GetEventTarget(event); |
| 292 if (!target) | 261 if (!target) |
| 293 return; | 262 return; |
| 294 | 263 |
| 295 event->SetHandled(); | 264 event->SetHandled(); |
| 296 if (event->type() != ui::ET_MOUSE_RELEASED) | 265 if (event->type() != ui::ET_MOUSE_RELEASED) |
| 297 return; | 266 return; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && | 315 if (new_window->parent()->id() == kSwitchableWindowContainerIds[i] && |
| 347 !::wm::GetTransientParent(new_window)) { | 316 !::wm::GetTransientParent(new_window)) { |
| 348 // The new window is in one of the switchable containers, abort overview. | 317 // The new window is in one of the switchable containers, abort overview. |
| 349 CancelSelection(); | 318 CancelSelection(); |
| 350 return; | 319 return; |
| 351 } | 320 } |
| 352 } | 321 } |
| 353 } | 322 } |
| 354 | 323 |
| 355 void WindowSelector::OnWindowDestroying(aura::Window* window) { | 324 void WindowSelector::OnWindowDestroying(aura::Window* window) { |
| 356 // window is one of a container, the restore_focus_window and/or | 325 WindowSelectorItem* removed_item = NULL; |
| 357 // one of the selectable windows in overview. | 326 |
| 358 ScopedVector<WindowSelectorItem>::iterator iter = | 327 ScopedVector<WindowGrid>::iterator grid_iter; |
| 359 std::find_if(windows_.begin(), windows_.end(), | 328 for (ScopedVector<WindowGrid>::iterator iter = grid_list_.begin(); |
| 360 WindowSelectorItemComparator(window)); | 329 iter != grid_list_.end() && !removed_item; ++iter) { |
| 330 removed_item = (*iter)->RemoveWindow(window); | |
|
tdanderson
2014/05/28 16:01:19
I prefer the previous approach: using find_if to d
Nina
2014/05/29 17:12:24
Well, if I do it like that I think I'll have to fi
| |
| 331 grid_iter = iter; | |
| 332 } | |
| 333 | |
| 361 window->RemoveObserver(this); | 334 window->RemoveObserver(this); |
| 362 observed_windows_.erase(window); | 335 observed_windows_.erase(window); |
| 363 if (window == restore_focus_window_) | 336 if (window == restore_focus_window_) |
| 364 restore_focus_window_ = NULL; | 337 restore_focus_window_ = NULL; |
| 365 if (iter == windows_.end()) | 338 |
| 339 if (!removed_item) | |
| 366 return; | 340 return; |
| 367 | 341 |
| 368 (*iter)->RemoveWindow(window); | 342 windows_.erase(std::find(windows_.begin(), windows_.end(), removed_item)); |
| 369 // If there are still windows in this selector entry then the overview is | |
| 370 // still active and the active selection remains the same. | |
| 371 if (!(*iter)->empty()) | |
| 372 return; | |
| 373 | 343 |
| 374 windows_.erase(iter); | 344 if (grid_iter != grid_list_.end() && (*grid_iter)->empty()) { |
| 375 if (windows_.empty()) { | 345 grid_list_.erase(grid_iter); |
| 376 CancelSelection(); | 346 root_index_ = 0; |
| 377 return; | 347 if (grid_list_.size() == 0) |
| 348 CancelSelection(); | |
| 378 } | 349 } |
| 379 PositionWindows(true); | |
|
tdanderson
2014/05/28 16:01:19
Why was this removed?
Nina
2014/05/29 17:12:24
Because RemoveWindow rearranges the windows on its
| |
| 380 } | 350 } |
| 381 | 351 |
| 382 void WindowSelector::OnWindowBoundsChanged(aura::Window* window, | 352 void WindowSelector::OnWindowBoundsChanged(aura::Window* window, |
| 383 const gfx::Rect& old_bounds, | 353 const gfx::Rect& old_bounds, |
| 384 const gfx::Rect& new_bounds) { | 354 const gfx::Rect& new_bounds) { |
| 385 ScopedVector<WindowSelectorItem>::iterator iter = | 355 ScopedVector<WindowSelectorItem>::iterator iter = |
| 386 std::find_if(windows_.begin(), windows_.end(), | 356 std::find_if(windows_.begin(), windows_.end(), |
| 387 WindowSelectorItemTargetComparator(window)); | 357 WindowSelectorItemTargetComparator(window)); |
| 388 if (iter == windows_.end()) | 358 if (iter == windows_.end()) |
| 389 return; | 359 return; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 419 aura::client::GetFocusClient( | 389 aura::client::GetFocusClient( |
| 420 Shell::GetPrimaryRootWindow())->FocusWindow(NULL); | 390 Shell::GetPrimaryRootWindow())->FocusWindow(NULL); |
| 421 | 391 |
| 422 Shell* shell = Shell::GetInstance(); | 392 Shell* shell = Shell::GetInstance(); |
| 423 shell->OnOverviewModeStarting(); | 393 shell->OnOverviewModeStarting(); |
| 424 | 394 |
| 425 for (WindowSelectorItemList::iterator iter = windows_.begin(); | 395 for (WindowSelectorItemList::iterator iter = windows_.begin(); |
| 426 iter != windows_.end(); ++iter) { | 396 iter != windows_.end(); ++iter) { |
| 427 (*iter)->PrepareForOverview(); | 397 (*iter)->PrepareForOverview(); |
| 428 } | 398 } |
| 429 PositionWindows(/* animate */ true); | 399 PositionWindows(true); |
| 430 DCHECK(!windows_.empty()); | 400 DCHECK(!windows_.empty()); |
| 431 cursor_client_ = aura::client::GetCursorClient( | 401 cursor_client_ = aura::client::GetCursorClient( |
| 432 windows_.front()->GetRootWindow()); | 402 windows_.front()->GetRootWindow()); |
| 433 if (cursor_client_) { | 403 if (cursor_client_) { |
| 434 cursor_client_->SetCursor(ui::kCursorPointer); | 404 cursor_client_->SetCursor(ui::kCursorPointer); |
| 435 cursor_client_->ShowCursor(); | 405 cursor_client_->ShowCursor(); |
| 436 // TODO(flackr): Only prevent cursor changes for windows in the overview. | 406 // TODO(flackr): Only prevent cursor changes for windows in the overview. |
| 437 // This will be easier to do without exposing the overview mode code if the | 407 // This will be easier to do without exposing the overview mode code if the |
| 438 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved | 408 // cursor changes are moved to ToplevelWindowEventHandler::HandleMouseMoved |
| 439 // as suggested there. | 409 // as suggested there. |
| 440 cursor_client_->LockCursor(); | 410 cursor_client_->LockCursor(); |
| 441 } | 411 } |
| 442 shell->PrependPreTargetHandler(this); | 412 shell->PrependPreTargetHandler(this); |
| 443 shell->GetScreen()->AddObserver(this); | 413 shell->GetScreen()->AddObserver(this); |
| 444 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); | 414 shell->metrics()->RecordUserMetricsAction(UMA_WINDOW_OVERVIEW); |
| 445 HideAndTrackNonOverviewWindows(); | 415 HideAndTrackNonOverviewWindows(); |
| 446 // Send an a11y alert. | 416 // Send an a11y alert. |
| 447 shell->accessibility_delegate()->TriggerAccessibilityAlert( | 417 shell->accessibility_delegate()->TriggerAccessibilityAlert( |
| 448 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); | 418 A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED); |
| 449 | 419 |
| 450 UpdateShelfVisibility(); | 420 UpdateShelfVisibility(); |
| 451 } | 421 } |
| 452 | 422 |
| 453 void WindowSelector::PositionWindows(bool animate) { | 423 void WindowSelector::PositionWindows(bool animate) { |
| 424 grid_list_.clear(); | |
| 454 aura::Window::Windows root_window_list = Shell::GetAllRootWindows(); | 425 aura::Window::Windows root_window_list = Shell::GetAllRootWindows(); |
| 455 for (size_t i = 0; i < root_window_list.size(); ++i) | 426 for (size_t i = 0; i < root_window_list.size(); ++i) { |
| 456 PositionWindowsFromRoot(root_window_list[i], animate); | 427 std::vector<WindowSelectorItem*> windows; |
| 457 } | 428 for (WindowSelectorItemList::iterator iter = windows_.begin(); |
| 458 | 429 iter != windows_.end(); ++iter) { |
| 459 void WindowSelector::PositionWindowsFromRoot(aura::Window* root_window, | 430 if ((*iter)->GetRootWindow() == root_window_list[i]) |
| 460 bool animate) { | 431 windows.push_back(*iter); |
| 461 std::vector<WindowSelectorItem*> windows; | 432 } |
| 462 for (WindowSelectorItemList::iterator iter = windows_.begin(); | 433 if (!windows.empty()) |
| 463 iter != windows_.end(); ++iter) { | 434 grid_list_.push_back(new WindowGrid(root_window_list[i], windows)); |
| 464 if ((*iter)->GetRootWindow() == root_window) | |
| 465 windows.push_back(*iter); | |
| 466 } | |
| 467 | |
| 468 if (windows.empty()) | |
| 469 return; | |
| 470 | |
| 471 gfx::Size window_size; | |
| 472 gfx::Rect total_bounds = ScreenUtil::ConvertRectToScreen( | |
| 473 root_window, | |
| 474 ScreenUtil::GetDisplayWorkAreaBoundsInParent( | |
| 475 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer))); | |
| 476 | |
| 477 // Find the minimum number of windows per row that will fit all of the | |
| 478 // windows on screen. | |
| 479 size_t columns = std::max( | |
| 480 total_bounds.width() > total_bounds.height() ? kMinCardsMajor : 1, | |
| 481 static_cast<int>(ceil(sqrt(total_bounds.width() * windows.size() / | |
| 482 (kCardAspectRatio * total_bounds.height()))))); | |
| 483 size_t rows = ((windows.size() + columns - 1) / columns); | |
| 484 window_size.set_width(std::min( | |
| 485 static_cast<int>(total_bounds.width() / columns), | |
| 486 static_cast<int>(total_bounds.height() * kCardAspectRatio / rows))); | |
| 487 window_size.set_height(window_size.width() / kCardAspectRatio); | |
| 488 | |
| 489 // Calculate the X and Y offsets necessary to center the grid. | |
| 490 int x_offset = total_bounds.x() + ((windows.size() >= columns ? 0 : | |
| 491 (columns - windows.size()) * window_size.width()) + | |
| 492 (total_bounds.width() - columns * window_size.width())) / 2; | |
| 493 int y_offset = total_bounds.y() + (total_bounds.height() - | |
| 494 rows * window_size.height()) / 2; | |
| 495 for (size_t i = 0; i < windows.size(); ++i) { | |
| 496 gfx::Transform transform; | |
| 497 int column = i % columns; | |
| 498 int row = i / columns; | |
| 499 gfx::Rect target_bounds(window_size.width() * column + x_offset, | |
| 500 window_size.height() * row + y_offset, | |
| 501 window_size.width(), | |
| 502 window_size.height()); | |
| 503 target_bounds.Inset(kWindowMargin, kWindowMargin); | |
| 504 windows[i]->SetBounds(root_window, target_bounds, animate); | |
| 505 } | 435 } |
| 506 } | 436 } |
| 507 | 437 |
| 508 void WindowSelector::HideAndTrackNonOverviewWindows() { | 438 void WindowSelector::HideAndTrackNonOverviewWindows() { |
| 509 // Add the windows to hidden_windows first so that if any are destroyed | 439 // Add the windows to hidden_windows first so that if any are destroyed |
| 510 // while hiding them they are tracked. | 440 // while hiding them they are tracked. |
| 511 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 441 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 512 for (aura::Window::Windows::const_iterator root_iter = root_windows.begin(); | 442 for (aura::Window::Windows::const_iterator root_iter = root_windows.begin(); |
| 513 root_iter != root_windows.end(); ++root_iter) { | 443 root_iter != root_windows.end(); ++root_iter) { |
| 514 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { | 444 for (size_t i = 0; i < kSwitchableWindowContainerIdsLength; ++i) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 for (WindowSelectorItemList::iterator iter = windows_.begin(); | 505 for (WindowSelectorItemList::iterator iter = windows_.begin(); |
| 576 iter != windows_.end(); ++iter) { | 506 iter != windows_.end(); ++iter) { |
| 577 aura::Window* selected = (*iter)->TargetedWindow(window); | 507 aura::Window* selected = (*iter)->TargetedWindow(window); |
| 578 if (selected) | 508 if (selected) |
| 579 return selected; | 509 return selected; |
| 580 } | 510 } |
| 581 return NULL; | 511 return NULL; |
| 582 } | 512 } |
| 583 | 513 |
| 584 } // namespace ash | 514 } // namespace ash |
| OLD | NEW |