Chromium Code Reviews| 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 "ash/common/wm/window_cycle_list.h" | 5 #include "ash/common/wm/window_cycle_list.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "ash/common/wm/mru_window_tracker.h" | 10 #include "ash/common/wm/mru_window_tracker.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 namespace ash { | 33 namespace ash { |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 bool g_disable_initial_delay = false; | 37 bool g_disable_initial_delay = false; |
| 38 | 38 |
| 39 // Used for the highlight view and the shield (black background). | 39 // Used for the highlight view and the shield (black background). |
| 40 constexpr float kBackgroundCornerRadius = 4.f; | 40 constexpr float kBackgroundCornerRadius = 4.f; |
| 41 | 41 |
| 42 // Returns the window immediately below |window| in the current container. | |
| 43 WmWindow* GetWindowBelow(WmWindow* window) { | |
| 44 WmWindow* parent = window->GetParent(); | |
| 45 if (!parent) | |
| 46 return nullptr; | |
| 47 const WmWindow::Windows children = parent->GetChildren(); | |
| 48 auto iter = std::find(children.begin(), children.end(), window); | |
| 49 CHECK(*iter == window); | |
| 50 return (iter != children.begin()) ? *(iter - 1) : nullptr; | |
| 51 } | |
| 52 | |
| 53 // This background paints a |Painter| but fills the view's layer's size rather | 42 // This background paints a |Painter| but fills the view's layer's size rather |
| 54 // than the view's size. | 43 // than the view's size. |
| 55 class LayerFillBackgroundPainter : public views::Background { | 44 class LayerFillBackgroundPainter : public views::Background { |
| 56 public: | 45 public: |
| 57 explicit LayerFillBackgroundPainter(std::unique_ptr<views::Painter> painter) | 46 explicit LayerFillBackgroundPainter(std::unique_ptr<views::Painter> painter) |
| 58 : painter_(std::move(painter)) {} | 47 : painter_(std::move(painter)) {} |
| 59 | 48 |
| 60 ~LayerFillBackgroundPainter() override {} | 49 ~LayerFillBackgroundPainter() override {} |
| 61 | 50 |
| 62 void Paint(gfx::Canvas* canvas, views::View* view) const override { | 51 void Paint(gfx::Canvas* canvas, views::View* view) const override { |
| 63 views::Painter::PaintPainterAt(canvas, painter_.get(), | 52 views::Painter::PaintPainterAt(canvas, painter_.get(), |
| 64 gfx::Rect(view->layer()->size())); | 53 gfx::Rect(view->layer()->size())); |
| 65 } | 54 } |
| 66 | 55 |
| 67 private: | 56 private: |
| 68 std::unique_ptr<views::Painter> painter_; | 57 std::unique_ptr<views::Painter> painter_; |
| 69 | 58 |
| 70 DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); | 59 DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); |
| 71 }; | 60 }; |
| 72 | 61 |
| 73 } // namespace | 62 } // namespace |
| 74 | 63 |
| 75 // This class restores and moves a window to the front of the stacking order for | |
| 76 // the duration of the class's scope. | |
| 77 class ScopedShowWindow : public WmWindowObserver { | |
| 78 public: | |
| 79 ScopedShowWindow(); | |
| 80 ~ScopedShowWindow() override; | |
| 81 | |
| 82 // Show |window| at the top of the stacking order. | |
| 83 void Show(WmWindow* window); | |
| 84 | |
| 85 // Cancel restoring the window on going out of scope. | |
| 86 void CancelRestore(); | |
| 87 | |
| 88 private: | |
| 89 // WmWindowObserver: | |
| 90 void OnWindowTreeChanging(WmWindow* window, | |
| 91 const TreeChangeParams& params) override; | |
| 92 | |
| 93 // The window being shown. | |
| 94 WmWindow* window_; | |
| 95 | |
| 96 // The window immediately below where window_ belongs. | |
| 97 WmWindow* stack_window_above_; | |
| 98 | |
| 99 // If true, minimize window_ on going out of scope. | |
| 100 bool minimized_; | |
| 101 | |
| 102 DISALLOW_COPY_AND_ASSIGN(ScopedShowWindow); | |
| 103 }; | |
| 104 | |
| 105 // This view represents a single WmWindow by displaying a title and a thumbnail | 64 // This view represents a single WmWindow by displaying a title and a thumbnail |
| 106 // of the window's contents. | 65 // of the window's contents. |
| 107 class WindowPreviewView : public views::View, public WmWindowObserver { | 66 class WindowPreviewView : public views::View, public WmWindowObserver { |
| 108 public: | 67 public: |
| 109 explicit WindowPreviewView(WmWindow* window) | 68 explicit WindowPreviewView(WmWindow* window) |
| 110 : window_title_(new views::Label), | 69 : window_title_(new views::Label), |
| 111 preview_background_(new views::View), | 70 preview_background_(new views::View), |
| 112 mirror_view_(window->CreateViewWithRecreatedLayers().release()), | 71 mirror_view_(window->CreateViewWithRecreatedLayers().release()), |
| 113 window_observer_(this) { | 72 window_observer_(this) { |
| 114 window_observer_.Add(window); | 73 window_observer_.Add(window); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 mirror_container_->layer()->SetAnimator( | 344 mirror_container_->layer()->SetAnimator( |
| 386 ui::LayerAnimator::CreateImplicitAnimator()); | 345 ui::LayerAnimator::CreateImplicitAnimator()); |
| 387 // The selection highlight also animates all bounds changes and never | 346 // The selection highlight also animates all bounds changes and never |
| 388 // changes other animatable properties. | 347 // changes other animatable properties. |
| 389 highlight_view_->layer()->SetAnimator( | 348 highlight_view_->layer()->SetAnimator( |
| 390 ui::LayerAnimator::CreateImplicitAnimator()); | 349 ui::LayerAnimator::CreateImplicitAnimator()); |
| 391 } | 350 } |
| 392 } | 351 } |
| 393 | 352 |
| 394 void OnMouseCaptureLost() override { | 353 void OnMouseCaptureLost() override { |
| 395 WmShell::Get()->window_cycle_controller()->StopCycling(); | 354 WmShell::Get()->window_cycle_controller()->CancelCycling(); |
| 396 } | 355 } |
| 397 | 356 |
| 398 void OnPaintBackground(gfx::Canvas* canvas) override { | 357 void OnPaintBackground(gfx::Canvas* canvas) override { |
| 399 // We can't set a bg on the mirror container itself because the highlight | 358 // We can't set a bg on the mirror container itself because the highlight |
| 400 // view needs to be on top of the bg but behind the target windows. | 359 // view needs to be on top of the bg but behind the target windows. |
| 401 const gfx::RectF shield_bounds(mirror_container_->bounds()); | 360 const gfx::RectF shield_bounds(mirror_container_->bounds()); |
| 402 SkPaint paint; | 361 SkPaint paint; |
| 403 paint.setColor(SkColorSetA(SK_ColorBLACK, 0xE6)); | 362 paint.setColor(SkColorSetA(SK_ColorBLACK, 0xE6)); |
| 404 paint.setStyle(SkPaint::kFill_Style); | 363 paint.setStyle(SkPaint::kFill_Style); |
| 405 float corner_radius = 0.f; | 364 float corner_radius = 0.f; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 418 | 377 |
| 419 private: | 378 private: |
| 420 std::map<WmWindow*, views::View*> window_view_map_; | 379 std::map<WmWindow*, views::View*> window_view_map_; |
| 421 views::View* mirror_container_; | 380 views::View* mirror_container_; |
| 422 views::View* highlight_view_; | 381 views::View* highlight_view_; |
| 423 WmWindow* target_window_; | 382 WmWindow* target_window_; |
| 424 | 383 |
| 425 DISALLOW_COPY_AND_ASSIGN(WindowCycleView); | 384 DISALLOW_COPY_AND_ASSIGN(WindowCycleView); |
| 426 }; | 385 }; |
| 427 | 386 |
| 428 ScopedShowWindow::ScopedShowWindow() | |
|
varkha
2017/01/03 22:38:51
Since you are removing this pre-MD path, maybe upd
Evan Stade
2017/01/03 22:41:47
Done.
| |
| 429 : window_(nullptr), stack_window_above_(nullptr), minimized_(false) {} | |
| 430 | |
| 431 ScopedShowWindow::~ScopedShowWindow() { | |
| 432 if (window_) { | |
| 433 window_->GetParent()->RemoveObserver(this); | |
| 434 | |
| 435 // Restore window's stacking position. | |
| 436 if (stack_window_above_) | |
| 437 window_->GetParent()->StackChildAbove(window_, stack_window_above_); | |
| 438 else | |
| 439 window_->GetParent()->StackChildAtBottom(window_); | |
| 440 | |
| 441 // Restore minimized state. | |
| 442 if (minimized_) | |
| 443 window_->GetWindowState()->Minimize(); | |
| 444 } | |
| 445 } | |
| 446 | |
| 447 void ScopedShowWindow::Show(WmWindow* window) { | |
| 448 DCHECK(!window_); | |
| 449 window_ = window; | |
| 450 stack_window_above_ = GetWindowBelow(window); | |
| 451 minimized_ = window->GetWindowState()->IsMinimized(); | |
| 452 window_->GetParent()->AddObserver(this); | |
| 453 window_->Show(); | |
| 454 window_->GetWindowState()->Activate(); | |
| 455 } | |
| 456 | |
| 457 void ScopedShowWindow::CancelRestore() { | |
| 458 if (!window_) | |
| 459 return; | |
| 460 window_->GetParent()->RemoveObserver(this); | |
| 461 window_ = stack_window_above_ = nullptr; | |
| 462 } | |
| 463 | |
| 464 void ScopedShowWindow::OnWindowTreeChanging(WmWindow* window, | |
| 465 const TreeChangeParams& params) { | |
| 466 // Only interested in removal. | |
| 467 if (params.new_parent != nullptr) | |
| 468 return; | |
| 469 | |
| 470 if (params.target == window_) { | |
| 471 CancelRestore(); | |
| 472 } else if (params.target == stack_window_above_) { | |
| 473 // If the window this window was above is removed, use the next window down | |
| 474 // as the restore marker. | |
| 475 stack_window_above_ = GetWindowBelow(stack_window_above_); | |
| 476 } | |
| 477 } | |
| 478 | |
| 479 WindowCycleList::WindowCycleList(const WindowList& windows) | 387 WindowCycleList::WindowCycleList(const WindowList& windows) |
| 480 : windows_(windows), | 388 : windows_(windows), |
| 481 current_index_(0), | |
| 482 cycle_view_(nullptr), | |
| 483 cycle_ui_widget_(nullptr), | |
| 484 screen_observer_(this) { | 389 screen_observer_(this) { |
| 485 if (!ShouldShowUi()) | 390 if (!ShouldShowUi()) |
| 486 WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); | 391 WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); |
| 487 | 392 |
| 488 for (WmWindow* window : windows_) | 393 for (WmWindow* window : windows_) |
| 489 window->AddObserver(this); | 394 window->AddObserver(this); |
| 490 | 395 |
| 491 if (ShouldShowUi()) { | 396 if (ShouldShowUi()) { |
| 492 if (g_disable_initial_delay) { | 397 if (g_disable_initial_delay) { |
| 493 InitWindowCycleView(); | 398 InitWindowCycleView(); |
| 494 } else { | 399 } else { |
| 495 show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), | 400 show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), |
| 496 this, &WindowCycleList::InitWindowCycleView); | 401 this, &WindowCycleList::InitWindowCycleView); |
| 497 } | 402 } |
| 498 } | 403 } |
| 499 } | 404 } |
| 500 | 405 |
| 501 WindowCycleList::~WindowCycleList() { | 406 WindowCycleList::~WindowCycleList() { |
| 502 if (!ShouldShowUi()) | 407 if (!ShouldShowUi()) |
| 503 WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); | 408 WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); |
| 504 | 409 |
| 505 for (WmWindow* window : windows_) | 410 for (WmWindow* window : windows_) |
| 506 window->RemoveObserver(this); | 411 window->RemoveObserver(this); |
| 507 | 412 |
| 508 if (showing_window_) { | 413 if (!windows_.empty() && user_did_accept_) { |
| 509 showing_window_->CancelRestore(); | |
| 510 } else if (!windows_.empty()) { | |
| 511 WmWindow* target_window = windows_[current_index_]; | 414 WmWindow* target_window = windows_[current_index_]; |
| 512 target_window->Show(); | 415 target_window->Show(); |
| 513 target_window->GetWindowState()->Activate(); | 416 target_window->GetWindowState()->Activate(); |
| 514 } | 417 } |
| 515 | 418 |
| 516 if (cycle_ui_widget_) | 419 if (cycle_ui_widget_) |
| 517 cycle_ui_widget_->Close(); | 420 cycle_ui_widget_->Close(); |
| 518 } | 421 } |
| 519 | 422 |
| 520 void WindowCycleList::Step(WindowCycleController::Direction direction) { | 423 void WindowCycleList::Step(WindowCycleController::Direction direction) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 546 // Wrap to window list size. | 449 // Wrap to window list size. |
| 547 current_index_ = (current_index_ + windows_.size()) % windows_.size(); | 450 current_index_ = (current_index_ + windows_.size()) % windows_.size(); |
| 548 DCHECK(windows_[current_index_]); | 451 DCHECK(windows_[current_index_]); |
| 549 | 452 |
| 550 if (ShouldShowUi()) { | 453 if (ShouldShowUi()) { |
| 551 if (current_index_ > 1) | 454 if (current_index_ > 1) |
| 552 InitWindowCycleView(); | 455 InitWindowCycleView(); |
| 553 | 456 |
| 554 if (cycle_view_) | 457 if (cycle_view_) |
| 555 cycle_view_->SetTargetWindow(windows_[current_index_]); | 458 cycle_view_->SetTargetWindow(windows_[current_index_]); |
| 556 } else { | |
| 557 // Make sure the next window is visible. | |
| 558 showing_window_.reset(new ScopedShowWindow); | |
| 559 showing_window_->Show(windows_[current_index_]); | |
| 560 } | 459 } |
| 561 } | 460 } |
| 562 | 461 |
| 563 // static | 462 // static |
| 564 void WindowCycleList::DisableInitialDelayForTesting() { | 463 void WindowCycleList::DisableInitialDelayForTesting() { |
| 565 g_disable_initial_delay = true; | 464 g_disable_initial_delay = true; |
| 566 } | 465 } |
| 567 | 466 |
| 568 void WindowCycleList::OnWindowDestroying(WmWindow* window) { | 467 void WindowCycleList::OnWindowDestroying(WmWindow* window) { |
| 569 window->RemoveObserver(this); | 468 window->RemoveObserver(this); |
| 570 | 469 |
| 571 WindowList::iterator i = std::find(windows_.begin(), windows_.end(), window); | 470 WindowList::iterator i = std::find(windows_.begin(), windows_.end(), window); |
| 572 // TODO(oshima): Change this back to DCHECK once crbug.com/483491 is fixed. | 471 // TODO(oshima): Change this back to DCHECK once crbug.com/483491 is fixed. |
| 573 CHECK(i != windows_.end()); | 472 CHECK(i != windows_.end()); |
| 574 int removed_index = static_cast<int>(i - windows_.begin()); | 473 int removed_index = static_cast<int>(i - windows_.begin()); |
| 575 windows_.erase(i); | 474 windows_.erase(i); |
| 576 if (current_index_ > removed_index || | 475 if (current_index_ > removed_index || |
| 577 current_index_ == static_cast<int>(windows_.size())) { | 476 current_index_ == static_cast<int>(windows_.size())) { |
| 578 current_index_--; | 477 current_index_--; |
| 579 } | 478 } |
| 580 | 479 |
| 581 if (cycle_view_) { | 480 if (cycle_view_) { |
| 582 WmWindow* new_target_window = | 481 WmWindow* new_target_window = |
| 583 windows_.empty() ? nullptr : windows_[current_index_]; | 482 windows_.empty() ? nullptr : windows_[current_index_]; |
| 584 cycle_view_->HandleWindowDestruction(window, new_target_window); | 483 cycle_view_->HandleWindowDestruction(window, new_target_window); |
| 585 if (windows_.empty()) { | 484 if (windows_.empty()) { |
| 586 // This deletes us. | 485 // This deletes us. |
| 587 WmShell::Get()->window_cycle_controller()->StopCycling(); | 486 WmShell::Get()->window_cycle_controller()->CancelCycling(); |
| 588 return; | 487 return; |
| 589 } | 488 } |
| 590 } | 489 } |
| 591 } | 490 } |
| 592 | 491 |
| 593 void WindowCycleList::OnDisplayAdded(const display::Display& new_display) {} | 492 void WindowCycleList::OnDisplayAdded(const display::Display& new_display) {} |
| 594 | 493 |
| 595 void WindowCycleList::OnDisplayRemoved(const display::Display& old_display) {} | 494 void WindowCycleList::OnDisplayRemoved(const display::Display& old_display) {} |
| 596 | 495 |
| 597 void WindowCycleList::OnDisplayMetricsChanged(const display::Display& display, | 496 void WindowCycleList::OnDisplayMetricsChanged(const display::Display& display, |
| 598 uint32_t changed_metrics) { | 497 uint32_t changed_metrics) { |
| 599 if (cycle_ui_widget_ && | 498 if (cycle_ui_widget_ && |
| 600 display.id() == | 499 display.id() == |
| 601 display::Screen::GetScreen() | 500 display::Screen::GetScreen() |
| 602 ->GetDisplayNearestWindow(cycle_ui_widget_->GetNativeView()) | 501 ->GetDisplayNearestWindow(cycle_ui_widget_->GetNativeView()) |
| 603 .id() && | 502 .id() && |
| 604 (changed_metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION))) { | 503 (changed_metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION))) { |
| 605 WmShell::Get()->window_cycle_controller()->StopCycling(); | 504 WmShell::Get()->window_cycle_controller()->CancelCycling(); |
| 606 // |this| is deleted. | 505 // |this| is deleted. |
| 607 return; | 506 return; |
| 608 } | 507 } |
| 609 } | 508 } |
| 610 | 509 |
| 611 bool WindowCycleList::ShouldShowUi() { | 510 bool WindowCycleList::ShouldShowUi() { |
| 612 return windows_.size() > 1; | 511 return windows_.size() > 1; |
| 613 } | 512 } |
| 614 | 513 |
| 615 void WindowCycleList::InitWindowCycleView() { | 514 void WindowCycleList::InitWindowCycleView() { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 639 widget->Init(params); | 538 widget->Init(params); |
| 640 | 539 |
| 641 screen_observer_.Add(display::Screen::GetScreen()); | 540 screen_observer_.Add(display::Screen::GetScreen()); |
| 642 widget->Show(); | 541 widget->Show(); |
| 643 widget->SetCapture(cycle_view_); | 542 widget->SetCapture(cycle_view_); |
| 644 widget->set_auto_release_capture(false); | 543 widget->set_auto_release_capture(false); |
| 645 cycle_ui_widget_ = widget; | 544 cycle_ui_widget_ = widget; |
| 646 } | 545 } |
| 647 | 546 |
| 648 } // namespace ash | 547 } // namespace ash |
| OLD | NEW |