| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "athena/wm/window_overview_mode.h" | 5 #include "athena/wm/window_overview_mode.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" |
| 11 #include "base/macros.h" | 12 #include "base/macros.h" |
| 12 #include "ui/aura/scoped_window_targeter.h" | 13 #include "ui/aura/scoped_window_targeter.h" |
| 13 #include "ui/aura/window.h" | 14 #include "ui/aura/window.h" |
| 14 #include "ui/aura/window_delegate.h" | 15 #include "ui/aura/window_delegate.h" |
| 15 #include "ui/aura/window_property.h" | 16 #include "ui/aura/window_property.h" |
| 16 #include "ui/aura/window_targeter.h" | 17 #include "ui/aura/window_targeter.h" |
| 17 #include "ui/aura/window_tree_host.h" | 18 #include "ui/aura/window_tree_host.h" |
| 18 #include "ui/compositor/compositor.h" | 19 #include "ui/compositor/compositor.h" |
| 19 #include "ui/compositor/compositor_animation_observer.h" | 20 #include "ui/compositor/compositor_animation_observer.h" |
| 20 #include "ui/compositor/scoped_layer_animation_settings.h" | 21 #include "ui/compositor/scoped_layer_animation_settings.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 33 // The transform for when the window is at the bottom-most position. | 34 // The transform for when the window is at the bottom-most position. |
| 34 gfx::Transform bottom; | 35 gfx::Transform bottom; |
| 35 | 36 |
| 36 // The current overview state of the window. 0.f means the window is at the | 37 // The current overview state of the window. 0.f means the window is at the |
| 37 // topmost position. 1.f means the window is at the bottom-most position. | 38 // topmost position. 1.f means the window is at the bottom-most position. |
| 38 float progress; | 39 float progress; |
| 39 | 40 |
| 40 scoped_ptr<wm::Shadow> shadow; | 41 scoped_ptr<wm::Shadow> shadow; |
| 41 }; | 42 }; |
| 42 | 43 |
| 44 // Runs a callback at the end of the animation. This observe also destroys |
| 45 // itself afterwards. |
| 46 class ClosureAnimationObserver : public ui::ImplicitAnimationObserver { |
| 47 public: |
| 48 explicit ClosureAnimationObserver(const base::Closure& closure) |
| 49 : closure_(closure) { |
| 50 DCHECK(!closure_.is_null()); |
| 51 } |
| 52 private: |
| 53 virtual ~ClosureAnimationObserver() { |
| 54 } |
| 55 |
| 56 // ui::ImplicitAnimationObserver: |
| 57 virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 58 closure_.Run(); |
| 59 delete this; |
| 60 } |
| 61 |
| 62 const base::Closure closure_; |
| 63 |
| 64 DISALLOW_COPY_AND_ASSIGN(ClosureAnimationObserver); |
| 65 }; |
| 66 |
| 43 } // namespace | 67 } // namespace |
| 44 | 68 |
| 45 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) | 69 DECLARE_WINDOW_PROPERTY_TYPE(WindowOverviewState*) |
| 46 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, | 70 DEFINE_OWNED_WINDOW_PROPERTY_KEY(WindowOverviewState, |
| 47 kWindowOverviewState, | 71 kWindowOverviewState, |
| 48 NULL) | 72 NULL) |
| 49 namespace athena { | 73 namespace athena { |
| 50 | 74 |
| 51 namespace { | 75 namespace { |
| 52 | 76 |
| 53 bool ShouldShowWindowInOverviewMode(aura::Window* window) { | 77 bool ShouldShowWindowInOverviewMode(aura::Window* window) { |
| 54 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; | 78 return window->type() == ui::wm::WINDOW_TYPE_NORMAL; |
| 55 } | 79 } |
| 56 | 80 |
| 81 // Gets the transform for the window in its current state. |
| 82 gfx::Transform GetTransformForState(WindowOverviewState* state) { |
| 83 return gfx::Tween::TransformValueBetween(state->progress, |
| 84 state->top, |
| 85 state->bottom); |
| 86 } |
| 87 |
| 57 // Sets the progress-state for the window in the overview mode. | 88 // Sets the progress-state for the window in the overview mode. |
| 58 void SetWindowProgress(aura::Window* window, float progress) { | 89 void SetWindowProgress(aura::Window* window, float progress) { |
| 59 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); | 90 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 60 gfx::Transform transform = | |
| 61 gfx::Tween::TransformValueBetween(progress, state->top, state->bottom); | |
| 62 window->SetTransform(transform); | |
| 63 state->progress = progress; | 91 state->progress = progress; |
| 92 window->SetTransform(GetTransformForState(state)); |
| 64 } | 93 } |
| 65 | 94 |
| 66 // Resets the overview-related state for |window|. | 95 // Resets the overview-related state for |window|. |
| 67 void RestoreWindowState(aura::Window* window) { | 96 void RestoreWindowState(aura::Window* window) { |
| 68 window->ClearProperty(kWindowOverviewState); | 97 window->ClearProperty(kWindowOverviewState); |
| 69 | 98 |
| 70 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); | 99 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 71 settings.SetPreemptionStrategy( | 100 settings.SetPreemptionStrategy( |
| 72 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 101 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 73 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); | 102 settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(250)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 101 public ui::EventHandler, | 130 public ui::EventHandler, |
| 102 public ui::CompositorAnimationObserver { | 131 public ui::CompositorAnimationObserver { |
| 103 public: | 132 public: |
| 104 WindowOverviewModeImpl(aura::Window* container, | 133 WindowOverviewModeImpl(aura::Window* container, |
| 105 WindowOverviewModeDelegate* delegate) | 134 WindowOverviewModeDelegate* delegate) |
| 106 : container_(container), | 135 : container_(container), |
| 107 delegate_(delegate), | 136 delegate_(delegate), |
| 108 scoped_targeter_(new aura::ScopedWindowTargeter( | 137 scoped_targeter_(new aura::ScopedWindowTargeter( |
| 109 container, | 138 container, |
| 110 scoped_ptr<ui::EventTargeter>( | 139 scoped_ptr<ui::EventTargeter>( |
| 111 new StaticWindowTargeter(container)))) { | 140 new StaticWindowTargeter(container)))), |
| 141 dragged_window_(NULL) { |
| 112 container_->set_target_handler(this); | 142 container_->set_target_handler(this); |
| 113 | 143 |
| 114 // Prepare the desired transforms for all the windows, and set the initial | 144 // Prepare the desired transforms for all the windows, and set the initial |
| 115 // state on the windows. | 145 // state on the windows. |
| 116 ComputeTerminalStatesForAllWindows(); | 146 ComputeTerminalStatesForAllWindows(); |
| 117 SetInitialWindowStates(); | 147 SetInitialWindowStates(); |
| 118 } | 148 } |
| 119 | 149 |
| 120 virtual ~WindowOverviewModeImpl() { | 150 virtual ~WindowOverviewModeImpl() { |
| 121 container_->set_target_handler(container_->delegate()); | 151 container_->set_target_handler(container_->delegate()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 136 void ComputeTerminalStatesForAllWindows() { | 166 void ComputeTerminalStatesForAllWindows() { |
| 137 const aura::Window::Windows& windows = container_->children(); | 167 const aura::Window::Windows& windows = container_->children(); |
| 138 size_t window_count = std::count_if(windows.begin(), windows.end(), | 168 size_t window_count = std::count_if(windows.begin(), windows.end(), |
| 139 ShouldShowWindowInOverviewMode); | 169 ShouldShowWindowInOverviewMode); |
| 140 | 170 |
| 141 size_t index = 0; | 171 size_t index = 0; |
| 142 const gfx::Size container_size = container_->bounds().size(); | 172 const gfx::Size container_size = container_->bounds().size(); |
| 143 | 173 |
| 144 const int kGapBetweenWindowsBottom = 10; | 174 const int kGapBetweenWindowsBottom = 10; |
| 145 const int kGapBetweenWindowsTop = 5; | 175 const int kGapBetweenWindowsTop = 5; |
| 146 const float kMinScale = 0.6f; | |
| 147 const float kMaxScale = 0.95f; | |
| 148 | 176 |
| 149 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); | 177 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin(); |
| 150 iter != windows.rend(); | 178 iter != windows.rend(); |
| 151 ++iter) { | 179 ++iter) { |
| 152 aura::Window* window = (*iter); | 180 aura::Window* window = (*iter); |
| 153 if (!ShouldShowWindowInOverviewMode(window)) | 181 if (!ShouldShowWindowInOverviewMode(window)) |
| 154 continue; | 182 continue; |
| 155 | 183 |
| 156 gfx::Transform top_transform; | 184 gfx::Transform top_transform; |
| 157 int top = (window_count - index - 1) * kGapBetweenWindowsTop; | 185 int top = (window_count - index - 1) * kGapBetweenWindowsTop; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 if (!compositor->HasAnimationObserver(this)) | 332 if (!compositor->HasAnimationObserver(this)) |
| 305 compositor->AddAnimationObserver(this); | 333 compositor->AddAnimationObserver(this); |
| 306 } | 334 } |
| 307 | 335 |
| 308 void RemoveAnimationObserver() { | 336 void RemoveAnimationObserver() { |
| 309 ui::Compositor* compositor = container_->GetHost()->compositor(); | 337 ui::Compositor* compositor = container_->GetHost()->compositor(); |
| 310 if (compositor->HasAnimationObserver(this)) | 338 if (compositor->HasAnimationObserver(this)) |
| 311 compositor->RemoveAnimationObserver(this); | 339 compositor->RemoveAnimationObserver(this); |
| 312 } | 340 } |
| 313 | 341 |
| 342 void DragWindow(const ui::GestureEvent& event) { |
| 343 CHECK(dragged_window_); |
| 344 CHECK_EQ(ui::ET_GESTURE_SCROLL_UPDATE, event.type()); |
| 345 gfx::Vector2dF dragged_distance = |
| 346 dragged_start_location_ - event.location(); |
| 347 WindowOverviewState* dragged_state = |
| 348 dragged_window_->GetProperty(kWindowOverviewState); |
| 349 CHECK(dragged_state); |
| 350 gfx::Transform transform = GetTransformForState(dragged_state); |
| 351 transform.Translate(-dragged_distance.x(), 0); |
| 352 dragged_window_->SetTransform(transform); |
| 353 |
| 354 float ratio = std::min( |
| 355 1.f, std::abs(dragged_distance.x()) / kMinDistanceForDismissal); |
| 356 float opacity = |
| 357 gfx::Tween::FloatValueBetween(ratio, kMaxOpacity, kMinOpacity); |
| 358 dragged_window_->layer()->SetOpacity(opacity); |
| 359 } |
| 360 |
| 361 bool ShouldCloseDragWindow(const ui::GestureEvent& event) const { |
| 362 gfx::Vector2dF dragged_distance = |
| 363 dragged_start_location_ - event.location(); |
| 364 if (event.type() == ui::ET_GESTURE_SCROLL_END) |
| 365 return std::abs(dragged_distance.x()) >= kMinDistanceForDismissal; |
| 366 CHECK_EQ(ui::ET_SCROLL_FLING_START, event.type()); |
| 367 const bool dragging_towards_right = dragged_distance.x() < 0; |
| 368 const bool swipe_towards_right = event.details().velocity_x() > 0; |
| 369 if (dragging_towards_right != swipe_towards_right) |
| 370 return false; |
| 371 const float kMinVelocityForDismissal = 500.f; |
| 372 return std::abs(event.details().velocity_x()) > kMinVelocityForDismissal; |
| 373 } |
| 374 |
| 375 void CloseDragWindow(const ui::GestureEvent& gesture) { |
| 376 // Animate |dragged_window_| offscreen first, then destroy it. |
| 377 ui::ScopedLayerAnimationSettings settings( |
| 378 dragged_window_->layer()->GetAnimator()); |
| 379 settings.SetPreemptionStrategy( |
| 380 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 381 settings.AddObserver(new ClosureAnimationObserver( |
| 382 base::Bind(&base::DeletePointer<aura::Window>, dragged_window_))); |
| 383 |
| 384 WindowOverviewState* dragged_state = |
| 385 dragged_window_->GetProperty(kWindowOverviewState); |
| 386 CHECK(dragged_state); |
| 387 gfx::Transform transform = dragged_window_->layer()->transform(); |
| 388 gfx::RectF transformed_bounds = dragged_window_->bounds(); |
| 389 transform.TransformRect(&transformed_bounds); |
| 390 float transform_x = 0.f; |
| 391 if (gesture.location().x() > dragged_start_location_.x()) |
| 392 transform_x = container_->bounds().right() - transformed_bounds.x(); |
| 393 else |
| 394 transform_x = -(transformed_bounds.x() + transformed_bounds.width()); |
| 395 float scale = gfx::Tween::FloatValueBetween( |
| 396 dragged_state->progress, kMinScale, kMaxScale); |
| 397 transform.Translate(transform_x / scale, 0); |
| 398 dragged_window_->SetTransform(transform); |
| 399 dragged_window_->layer()->SetOpacity(kMinOpacity); |
| 400 |
| 401 // Move the windows behind |dragged_window_| in the stack forward one step. |
| 402 const aura::Window::Windows& list = container_->children(); |
| 403 for (aura::Window::Windows::const_iterator iter = list.begin(); |
| 404 iter != list.end() && *iter != dragged_window_; |
| 405 ++iter) { |
| 406 aura::Window* window = *iter; |
| 407 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); |
| 408 settings.SetPreemptionStrategy( |
| 409 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 410 WindowOverviewState* state = window->GetProperty(kWindowOverviewState); |
| 411 |
| 412 aura::Window* next = *(iter + 1); |
| 413 WindowOverviewState* next_state = next->GetProperty(kWindowOverviewState); |
| 414 state->top = next_state->top; |
| 415 state->bottom = next_state->bottom; |
| 416 SetWindowProgress(window, next_state->progress); |
| 417 } |
| 418 |
| 419 dragged_window_ = NULL; |
| 420 } |
| 421 |
| 422 void RestoreDragWindow() { |
| 423 CHECK(dragged_window_); |
| 424 WindowOverviewState* dragged_state = |
| 425 dragged_window_->GetProperty(kWindowOverviewState); |
| 426 CHECK(dragged_state); |
| 427 |
| 428 ui::ScopedLayerAnimationSettings settings( |
| 429 dragged_window_->layer()->GetAnimator()); |
| 430 settings.SetPreemptionStrategy( |
| 431 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 432 dragged_window_->SetTransform(GetTransformForState(dragged_state)); |
| 433 dragged_window_->layer()->SetOpacity(1.f); |
| 434 dragged_window_ = NULL; |
| 435 } |
| 436 |
| 314 // ui::EventHandler: | 437 // ui::EventHandler: |
| 315 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { | 438 virtual void OnMouseEvent(ui::MouseEvent* mouse) OVERRIDE { |
| 316 if (mouse->type() == ui::ET_MOUSE_PRESSED) { | 439 if (mouse->type() == ui::ET_MOUSE_PRESSED) { |
| 317 aura::Window* select = SelectWindowAt(mouse); | 440 aura::Window* select = SelectWindowAt(mouse); |
| 318 if (select) { | 441 if (select) { |
| 319 mouse->SetHandled(); | 442 mouse->SetHandled(); |
| 320 delegate_->OnSelectWindow(select); | 443 delegate_->OnSelectWindow(select); |
| 321 } | 444 } |
| 322 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { | 445 } else if (mouse->type() == ui::ET_MOUSEWHEEL) { |
| 323 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); | 446 DoScroll(static_cast<ui::MouseWheelEvent*>(mouse)->y_offset()); |
| 324 } | 447 } |
| 325 } | 448 } |
| 326 | 449 |
| 327 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { | 450 virtual void OnScrollEvent(ui::ScrollEvent* scroll) OVERRIDE { |
| 328 if (scroll->type() == ui::ET_SCROLL) | 451 if (scroll->type() == ui::ET_SCROLL) |
| 329 DoScroll(scroll->y_offset()); | 452 DoScroll(scroll->y_offset()); |
| 330 } | 453 } |
| 331 | 454 |
| 332 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { | 455 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE { |
| 333 if (gesture->type() == ui::ET_GESTURE_TAP) { | 456 if (gesture->type() == ui::ET_GESTURE_TAP) { |
| 334 aura::Window* select = SelectWindowAt(gesture); | 457 aura::Window* select = SelectWindowAt(gesture); |
| 335 if (select) { | 458 if (select) { |
| 336 gesture->SetHandled(); | 459 gesture->SetHandled(); |
| 337 delegate_->OnSelectWindow(select); | 460 delegate_->OnSelectWindow(select); |
| 338 } | 461 } |
| 462 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) { |
| 463 if (std::abs(gesture->details().scroll_x_hint()) > |
| 464 std::abs(gesture->details().scroll_y_hint()) * 2) { |
| 465 dragged_start_location_ = gesture->location(); |
| 466 dragged_window_ = SelectWindowAt(gesture); |
| 467 } |
| 339 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { | 468 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) { |
| 340 DoScroll(gesture->details().scroll_y()); | 469 if (dragged_window_) |
| 470 DragWindow(*gesture); |
| 471 else |
| 472 DoScroll(gesture->details().scroll_y()); |
| 473 gesture->SetHandled(); |
| 474 } else if (gesture->type() == ui::ET_GESTURE_SCROLL_END) { |
| 475 if (dragged_window_) { |
| 476 if (ShouldCloseDragWindow(*gesture)) |
| 477 CloseDragWindow(*gesture); |
| 478 else |
| 479 RestoreDragWindow(); |
| 480 } |
| 341 gesture->SetHandled(); | 481 gesture->SetHandled(); |
| 342 } else if (gesture->type() == ui::ET_SCROLL_FLING_START) { | 482 } else if (gesture->type() == ui::ET_SCROLL_FLING_START) { |
| 343 CreateFlingerFor(*gesture); | 483 if (dragged_window_) { |
| 344 AddAnimationObserver(); | 484 if (ShouldCloseDragWindow(*gesture)) |
| 485 CloseDragWindow(*gesture); |
| 486 else |
| 487 RestoreDragWindow(); |
| 488 } else { |
| 489 CreateFlingerFor(*gesture); |
| 490 AddAnimationObserver(); |
| 491 } |
| 345 gesture->SetHandled(); | 492 gesture->SetHandled(); |
| 346 } else if (gesture->type() == ui::ET_GESTURE_TAP_DOWN && fling_) { | 493 } else if (gesture->type() == ui::ET_GESTURE_TAP_DOWN) { |
| 347 fling_.reset(); | 494 if (fling_) { |
| 348 RemoveAnimationObserver(); | 495 fling_.reset(); |
| 349 gesture->SetHandled(); | 496 RemoveAnimationObserver(); |
| 497 gesture->SetHandled(); |
| 498 } |
| 499 dragged_window_ = NULL; |
| 350 } | 500 } |
| 351 } | 501 } |
| 352 | 502 |
| 353 // ui::CompositorAnimationObserver: | 503 // ui::CompositorAnimationObserver: |
| 354 virtual void OnAnimationStep(base::TimeTicks timestamp) OVERRIDE { | 504 virtual void OnAnimationStep(base::TimeTicks timestamp) OVERRIDE { |
| 355 CHECK(fling_); | 505 CHECK(fling_); |
| 356 if (fling_->start_timestamp() > timestamp) | 506 if (fling_->start_timestamp() > timestamp) |
| 357 return; | 507 return; |
| 358 gfx::Vector2dF scroll = fling_->GetScrollAmountAtTime(timestamp); | 508 gfx::Vector2dF scroll = fling_->GetScrollAmountAtTime(timestamp); |
| 359 if (scroll.IsZero()) { | 509 if (scroll.IsZero()) { |
| 360 fling_.reset(); | 510 fling_.reset(); |
| 361 RemoveAnimationObserver(); | 511 RemoveAnimationObserver(); |
| 362 } else { | 512 } else { |
| 363 DoScroll(scroll.y()); | 513 DoScroll(scroll.y()); |
| 364 } | 514 } |
| 365 } | 515 } |
| 366 | 516 |
| 517 const int kMinDistanceForDismissal = 300; |
| 518 const float kMinScale = 0.6f; |
| 519 const float kMaxScale = 0.95f; |
| 520 const float kMaxOpacity = 1.0f; |
| 521 const float kMinOpacity = 0.2f; |
| 522 |
| 367 aura::Window* container_; | 523 aura::Window* container_; |
| 368 WindowOverviewModeDelegate* delegate_; | 524 WindowOverviewModeDelegate* delegate_; |
| 369 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; | 525 scoped_ptr<aura::ScopedWindowTargeter> scoped_targeter_; |
| 370 scoped_ptr<ui::FlingCurve> fling_; | 526 scoped_ptr<ui::FlingCurve> fling_; |
| 371 | 527 |
| 528 aura::Window* dragged_window_; |
| 529 gfx::Point dragged_start_location_; |
| 530 |
| 372 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); | 531 DISALLOW_COPY_AND_ASSIGN(WindowOverviewModeImpl); |
| 373 }; | 532 }; |
| 374 | 533 |
| 375 } // namespace | 534 } // namespace |
| 376 | 535 |
| 377 // static | 536 // static |
| 378 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( | 537 scoped_ptr<WindowOverviewMode> WindowOverviewMode::Create( |
| 379 aura::Window* container, | 538 aura::Window* container, |
| 380 WindowOverviewModeDelegate* delegate) { | 539 WindowOverviewModeDelegate* delegate) { |
| 381 return scoped_ptr<WindowOverviewMode>( | 540 return scoped_ptr<WindowOverviewMode>( |
| 382 new WindowOverviewModeImpl(container, delegate)); | 541 new WindowOverviewModeImpl(container, delegate)); |
| 383 } | 542 } |
| 384 | 543 |
| 385 } // namespace athena | 544 } // namespace athena |
| OLD | NEW |