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/wm/window_cycle_list.h" | 5 #include "ash/wm/window_cycle_list.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "ash/public/cpp/shell_window_ids.h" | 10 #include "ash/public/cpp/shell_window_ids.h" |
11 #include "ash/root_window_controller.h" | 11 #include "ash/root_window_controller.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
13 #include "ash/wm/mru_window_tracker.h" | 13 #include "ash/wm/mru_window_tracker.h" |
| 14 #include "ash/wm/window_mirror_view.h" |
14 #include "ash/wm/window_state.h" | 15 #include "ash/wm/window_state.h" |
| 16 #include "ash/wm/window_state_aura.h" |
| 17 #include "ash/wm/window_util.h" |
15 #include "ash/wm_window.h" | 18 #include "ash/wm_window.h" |
16 #include "base/command_line.h" | 19 #include "base/command_line.h" |
17 #include "ui/accessibility/ax_node_data.h" | 20 #include "ui/accessibility/ax_node_data.h" |
18 #include "ui/compositor/scoped_layer_animation_settings.h" | 21 #include "ui/compositor/scoped_layer_animation_settings.h" |
19 #include "ui/display/display.h" | 22 #include "ui/display/display.h" |
20 #include "ui/display/screen.h" | 23 #include "ui/display/screen.h" |
21 #include "ui/gfx/canvas.h" | 24 #include "ui/gfx/canvas.h" |
22 #include "ui/views/background.h" | 25 #include "ui/views/background.h" |
23 #include "ui/views/border.h" | 26 #include "ui/views/border.h" |
24 #include "ui/views/controls/label.h" | 27 #include "ui/views/controls/label.h" |
(...skipping 28 matching lines...) Expand all Loading... |
53 } | 56 } |
54 | 57 |
55 private: | 58 private: |
56 std::unique_ptr<views::Painter> painter_; | 59 std::unique_ptr<views::Painter> painter_; |
57 | 60 |
58 DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); | 61 DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); |
59 }; | 62 }; |
60 | 63 |
61 } // namespace | 64 } // namespace |
62 | 65 |
63 // This view represents a single WmWindow by displaying a title and a thumbnail | 66 // This view represents a single aura::Window by displaying a title and a |
64 // of the window's contents. | 67 // thumbnail of the window's contents. |
65 class WindowPreviewView : public views::View, public aura::WindowObserver { | 68 class WindowPreviewView : public views::View, public aura::WindowObserver { |
66 public: | 69 public: |
67 explicit WindowPreviewView(WmWindow* window) | 70 explicit WindowPreviewView(aura::Window* window) |
68 : window_title_(new views::Label), | 71 : window_title_(new views::Label), |
69 preview_background_(new views::View), | 72 preview_background_(new views::View), |
70 mirror_view_(window->CreateViewWithRecreatedLayers().release()), | 73 mirror_view_(new wm::WindowMirrorView(window)), |
71 window_observer_(this) { | 74 window_observer_(this) { |
72 window_observer_.Add(window->aura_window()); | 75 window_observer_.Add(window); |
73 window_title_->SetText(window->aura_window()->GetTitle()); | 76 window_title_->SetText(window->GetTitle()); |
74 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 77 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
75 window_title_->SetEnabledColor(SK_ColorWHITE); | 78 window_title_->SetEnabledColor(SK_ColorWHITE); |
76 window_title_->SetAutoColorReadabilityEnabled(false); | 79 window_title_->SetAutoColorReadabilityEnabled(false); |
77 // Background is not fully opaque, so subpixel rendering won't look good. | 80 // Background is not fully opaque, so subpixel rendering won't look good. |
78 window_title_->SetSubpixelRenderingEnabled(false); | 81 window_title_->SetSubpixelRenderingEnabled(false); |
79 // The base font is 12pt (for English) so this comes out to 14pt. | 82 // The base font is 12pt (for English) so this comes out to 14pt. |
80 const int kLabelSizeDelta = 2; | 83 const int kLabelSizeDelta = 2; |
81 window_title_->SetFontList( | 84 window_title_->SetFontList( |
82 window_title_->font_list().DeriveWithSizeDelta(kLabelSizeDelta)); | 85 window_title_->font_list().DeriveWithSizeDelta(kLabelSizeDelta)); |
83 const int kAboveLabelPadding = 5; | 86 const int kAboveLabelPadding = 5; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 const int kBetweenChildPaddingDip = 10; | 231 const int kBetweenChildPaddingDip = 10; |
229 views::BoxLayout* layout = new views::BoxLayout( | 232 views::BoxLayout* layout = new views::BoxLayout( |
230 views::BoxLayout::kHorizontal, kInsideBorderPaddingDip, | 233 views::BoxLayout::kHorizontal, kInsideBorderPaddingDip, |
231 kInsideBorderPaddingDip, kBetweenChildPaddingDip); | 234 kInsideBorderPaddingDip, kBetweenChildPaddingDip); |
232 layout->set_cross_axis_alignment( | 235 layout->set_cross_axis_alignment( |
233 views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); | 236 views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); |
234 mirror_container_->SetLayoutManager(layout); | 237 mirror_container_->SetLayoutManager(layout); |
235 mirror_container_->SetPaintToLayer(); | 238 mirror_container_->SetPaintToLayer(); |
236 mirror_container_->layer()->SetFillsBoundsOpaquely(false); | 239 mirror_container_->layer()->SetFillsBoundsOpaquely(false); |
237 | 240 |
238 for (WmWindow* window : windows) { | 241 for (auto* window : windows) { |
239 // |mirror_container_| owns |view|. | 242 // |mirror_container_| owns |view|. |
240 views::View* view = new WindowPreviewView(window); | 243 views::View* view = new WindowPreviewView(window); |
241 window_view_map_[window] = view; | 244 window_view_map_[window] = view; |
242 mirror_container_->AddChildView(view); | 245 mirror_container_->AddChildView(view); |
243 } | 246 } |
244 | 247 |
245 // The background needs to be painted to fill the layer, not the View, | 248 // The background needs to be painted to fill the layer, not the View, |
246 // because the layer animates bounds changes but the View's bounds change | 249 // because the layer animates bounds changes but the View's bounds change |
247 // immediately. | 250 // immediately. |
248 highlight_view_->set_background(new LayerFillBackgroundPainter( | 251 highlight_view_->set_background(new LayerFillBackgroundPainter( |
249 views::Painter::CreateRoundRectWith1PxBorderPainter( | 252 views::Painter::CreateRoundRectWith1PxBorderPainter( |
250 SkColorSetA(SK_ColorWHITE, 0x4D), SkColorSetA(SK_ColorWHITE, 0x33), | 253 SkColorSetA(SK_ColorWHITE, 0x4D), SkColorSetA(SK_ColorWHITE, 0x33), |
251 kBackgroundCornerRadius))); | 254 kBackgroundCornerRadius))); |
252 highlight_view_->SetPaintToLayer(); | 255 highlight_view_->SetPaintToLayer(); |
253 | 256 |
254 highlight_view_->layer()->SetFillsBoundsOpaquely(false); | 257 highlight_view_->layer()->SetFillsBoundsOpaquely(false); |
255 | 258 |
256 AddChildView(highlight_view_); | 259 AddChildView(highlight_view_); |
257 AddChildView(mirror_container_); | 260 AddChildView(mirror_container_); |
258 } | 261 } |
259 | 262 |
260 ~WindowCycleView() override {} | 263 ~WindowCycleView() override {} |
261 | 264 |
262 void SetTargetWindow(WmWindow* target) { | 265 void SetTargetWindow(aura::Window* target) { |
263 target_window_ = target; | 266 target_window_ = target; |
264 if (GetWidget()) { | 267 if (GetWidget()) { |
265 Layout(); | 268 Layout(); |
266 if (target_window_) | 269 if (target_window_) |
267 window_view_map_[target_window_]->RequestFocus(); | 270 window_view_map_[target_window_]->RequestFocus(); |
268 } | 271 } |
269 } | 272 } |
270 | 273 |
271 void HandleWindowDestruction(WmWindow* destroying_window, | 274 void HandleWindowDestruction(aura::Window* destroying_window, |
272 WmWindow* new_target) { | 275 aura::Window* new_target) { |
273 auto view_iter = window_view_map_.find(destroying_window); | 276 auto view_iter = window_view_map_.find(destroying_window); |
274 views::View* preview = view_iter->second; | 277 views::View* preview = view_iter->second; |
275 views::View* parent = preview->parent(); | 278 views::View* parent = preview->parent(); |
276 DCHECK_EQ(mirror_container_, parent); | 279 DCHECK_EQ(mirror_container_, parent); |
277 window_view_map_.erase(view_iter); | 280 window_view_map_.erase(view_iter); |
278 delete preview; | 281 delete preview; |
279 // With one of its children now gone, we must re-layout |mirror_container_|. | 282 // With one of its children now gone, we must re-layout |mirror_container_|. |
280 // This must happen before SetTargetWindow() to make sure our own Layout() | 283 // This must happen before SetTargetWindow() to make sure our own Layout() |
281 // works correctly when it's calculating highlight bounds. | 284 // works correctly when it's calculating highlight bounds. |
282 parent->Layout(); | 285 parent->Layout(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 flags.setAntiAlias(true); | 364 flags.setAntiAlias(true); |
362 corner_radius = kBackgroundCornerRadius; | 365 corner_radius = kBackgroundCornerRadius; |
363 } | 366 } |
364 canvas->DrawRoundRect(shield_bounds, corner_radius, flags); | 367 canvas->DrawRoundRect(shield_bounds, corner_radius, flags); |
365 } | 368 } |
366 | 369 |
367 View* GetInitiallyFocusedView() override { | 370 View* GetInitiallyFocusedView() override { |
368 return window_view_map_[target_window_]; | 371 return window_view_map_[target_window_]; |
369 } | 372 } |
370 | 373 |
371 WmWindow* target_window() { return target_window_; } | 374 aura::Window* target_window() { return target_window_; } |
372 | 375 |
373 private: | 376 private: |
374 std::map<WmWindow*, views::View*> window_view_map_; | 377 std::map<aura::Window*, views::View*> window_view_map_; |
375 views::View* mirror_container_; | 378 views::View* mirror_container_; |
376 views::View* highlight_view_; | 379 views::View* highlight_view_; |
377 WmWindow* target_window_; | 380 aura::Window* target_window_; |
378 | 381 |
379 DISALLOW_COPY_AND_ASSIGN(WindowCycleView); | 382 DISALLOW_COPY_AND_ASSIGN(WindowCycleView); |
380 }; | 383 }; |
381 | 384 |
382 WindowCycleList::WindowCycleList(const WindowList& windows) | 385 WindowCycleList::WindowCycleList(const WindowList& windows) |
383 : windows_(windows), | 386 : windows_(windows), |
384 screen_observer_(this) { | 387 screen_observer_(this) { |
385 if (!ShouldShowUi()) | 388 if (!ShouldShowUi()) |
386 Shell::Get()->mru_window_tracker()->SetIgnoreActivations(true); | 389 Shell::Get()->mru_window_tracker()->SetIgnoreActivations(true); |
387 | 390 |
388 for (WmWindow* window : windows_) | 391 for (auto* window : windows_) |
389 window->aura_window()->AddObserver(this); | 392 window->AddObserver(this); |
390 | 393 |
391 if (ShouldShowUi()) { | 394 if (ShouldShowUi()) { |
392 if (g_disable_initial_delay) { | 395 if (g_disable_initial_delay) { |
393 InitWindowCycleView(); | 396 InitWindowCycleView(); |
394 } else { | 397 } else { |
395 show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), | 398 show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), |
396 this, &WindowCycleList::InitWindowCycleView); | 399 this, &WindowCycleList::InitWindowCycleView); |
397 } | 400 } |
398 } | 401 } |
399 } | 402 } |
400 | 403 |
401 WindowCycleList::~WindowCycleList() { | 404 WindowCycleList::~WindowCycleList() { |
402 if (!ShouldShowUi()) | 405 if (!ShouldShowUi()) |
403 Shell::Get()->mru_window_tracker()->SetIgnoreActivations(false); | 406 Shell::Get()->mru_window_tracker()->SetIgnoreActivations(false); |
404 | 407 |
405 for (WmWindow* window : windows_) | 408 for (auto* window : windows_) |
406 window->aura_window()->RemoveObserver(this); | 409 window->RemoveObserver(this); |
407 | 410 |
408 if (!windows_.empty() && user_did_accept_) { | 411 if (!windows_.empty() && user_did_accept_) { |
409 WmWindow* target_window = windows_[current_index_]; | 412 auto* target_window = windows_[current_index_]; |
410 target_window->Show(); | 413 target_window->Show(); |
411 target_window->GetWindowState()->Activate(); | 414 wm::GetWindowState(target_window)->Activate(); |
412 } | 415 } |
413 | 416 |
414 if (cycle_ui_widget_) | 417 if (cycle_ui_widget_) |
415 cycle_ui_widget_->Close(); | 418 cycle_ui_widget_->Close(); |
416 | 419 |
417 // |this| is responsible for notifying |cycle_view_| when windows are | 420 // |this| is responsible for notifying |cycle_view_| when windows are |
418 // destroyed. Since |this| is going away, clobber |cycle_view_|. Otherwise | 421 // destroyed. Since |this| is going away, clobber |cycle_view_|. Otherwise |
419 // there will be a race where a window closes after now but before the | 422 // there will be a race where a window closes after now but before the |
420 // Widget::Close() call above actually destroys |cycle_view_|. See | 423 // Widget::Close() call above actually destroys |cycle_view_|. See |
421 // crbug.com/681207 | 424 // crbug.com/681207 |
422 if (cycle_view_) | 425 if (cycle_view_) |
423 cycle_view_->DestroyContents(); | 426 cycle_view_->DestroyContents(); |
424 } | 427 } |
425 | 428 |
426 void WindowCycleList::Step(WindowCycleController::Direction direction) { | 429 void WindowCycleList::Step(WindowCycleController::Direction direction) { |
427 if (windows_.empty()) | 430 if (windows_.empty()) |
428 return; | 431 return; |
429 | 432 |
430 // When there is only one window, we should give feedback to the user. If the | 433 // When there is only one window, we should give feedback to the user. If the |
431 // window is minimized, we should also show it. | 434 // window is minimized, we should also show it. |
432 if (windows_.size() == 1) { | 435 if (windows_.size() == 1) { |
433 windows_[0]->Animate(::wm::WINDOW_ANIMATION_TYPE_BOUNCE); | 436 ::wm::AnimateWindow(windows_[0], ::wm::WINDOW_ANIMATION_TYPE_BOUNCE); |
434 windows_[0]->Show(); | 437 windows_[0]->Show(); |
435 windows_[0]->GetWindowState()->Activate(); | 438 wm::GetWindowState(windows_[0])->Activate(); |
436 return; | 439 return; |
437 } | 440 } |
438 | 441 |
439 DCHECK(static_cast<size_t>(current_index_) < windows_.size()); | 442 DCHECK(static_cast<size_t>(current_index_) < windows_.size()); |
440 | 443 |
441 if (!cycle_view_ && current_index_ == 0) { | 444 if (!cycle_view_ && current_index_ == 0) { |
442 // Special case the situation where we're cycling forward but the MRU window | 445 // Special case the situation where we're cycling forward but the MRU window |
443 // is not active. This occurs when all windows are minimized. The starting | 446 // is not active. This occurs when all windows are minimized. The starting |
444 // window should be the first one rather than the second. | 447 // window should be the first one rather than the second. |
445 if (direction == WindowCycleController::FORWARD && !windows_[0]->IsActive()) | 448 if (direction == WindowCycleController::FORWARD && |
| 449 !wm::IsActiveWindow(windows_[0])) |
446 current_index_ = -1; | 450 current_index_ = -1; |
447 } | 451 } |
448 | 452 |
449 // We're in a valid cycle, so step forward or backward. | 453 // We're in a valid cycle, so step forward or backward. |
450 current_index_ += direction == WindowCycleController::FORWARD ? 1 : -1; | 454 current_index_ += direction == WindowCycleController::FORWARD ? 1 : -1; |
451 | 455 |
452 // Wrap to window list size. | 456 // Wrap to window list size. |
453 current_index_ = (current_index_ + windows_.size()) % windows_.size(); | 457 current_index_ = (current_index_ + windows_.size()) % windows_.size(); |
454 DCHECK(windows_[current_index_]); | 458 DCHECK(windows_[current_index_]); |
455 | 459 |
456 if (ShouldShowUi()) { | 460 if (ShouldShowUi()) { |
457 if (current_index_ > 1) | 461 if (current_index_ > 1) |
458 InitWindowCycleView(); | 462 InitWindowCycleView(); |
459 | 463 |
460 if (cycle_view_) | 464 if (cycle_view_) |
461 cycle_view_->SetTargetWindow(windows_[current_index_]); | 465 cycle_view_->SetTargetWindow(windows_[current_index_]); |
462 } | 466 } |
463 } | 467 } |
464 | 468 |
465 // static | 469 // static |
466 void WindowCycleList::DisableInitialDelayForTesting() { | 470 void WindowCycleList::DisableInitialDelayForTesting() { |
467 g_disable_initial_delay = true; | 471 g_disable_initial_delay = true; |
468 } | 472 } |
469 | 473 |
470 void WindowCycleList::OnWindowDestroying(aura::Window* window) { | 474 void WindowCycleList::OnWindowDestroying(aura::Window* window) { |
471 window->RemoveObserver(this); | 475 window->RemoveObserver(this); |
472 | 476 |
473 WindowList::iterator i = | 477 WindowList::iterator i = std::find(windows_.begin(), windows_.end(), window); |
474 std::find(windows_.begin(), windows_.end(), WmWindow::Get(window)); | |
475 // TODO(oshima): Change this back to DCHECK once crbug.com/483491 is fixed. | 478 // TODO(oshima): Change this back to DCHECK once crbug.com/483491 is fixed. |
476 CHECK(i != windows_.end()); | 479 CHECK(i != windows_.end()); |
477 int removed_index = static_cast<int>(i - windows_.begin()); | 480 int removed_index = static_cast<int>(i - windows_.begin()); |
478 windows_.erase(i); | 481 windows_.erase(i); |
479 if (current_index_ > removed_index || | 482 if (current_index_ > removed_index || |
480 current_index_ == static_cast<int>(windows_.size())) { | 483 current_index_ == static_cast<int>(windows_.size())) { |
481 current_index_--; | 484 current_index_--; |
482 } | 485 } |
483 | 486 |
484 if (cycle_view_) { | 487 if (cycle_view_) { |
485 WmWindow* new_target_window = | 488 auto* new_target_window = |
486 windows_.empty() ? nullptr : windows_[current_index_]; | 489 windows_.empty() ? nullptr : windows_[current_index_]; |
487 cycle_view_->HandleWindowDestruction(WmWindow::Get(window), | 490 cycle_view_->HandleWindowDestruction(window, new_target_window); |
488 new_target_window); | |
489 if (windows_.empty()) { | 491 if (windows_.empty()) { |
490 // This deletes us. | 492 // This deletes us. |
491 Shell::Get()->window_cycle_controller()->CancelCycling(); | 493 Shell::Get()->window_cycle_controller()->CancelCycling(); |
492 return; | 494 return; |
493 } | 495 } |
494 } | 496 } |
495 } | 497 } |
496 | 498 |
497 void WindowCycleList::OnDisplayAdded(const display::Display& new_display) {} | 499 void WindowCycleList::OnDisplayAdded(const display::Display& new_display) {} |
498 | 500 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 widget_rect.set_height(widget_height); | 544 widget_rect.set_height(widget_height); |
543 params.bounds = widget_rect; | 545 params.bounds = widget_rect; |
544 widget->Init(params); | 546 widget->Init(params); |
545 | 547 |
546 screen_observer_.Add(display::Screen::GetScreen()); | 548 screen_observer_.Add(display::Screen::GetScreen()); |
547 widget->Show(); | 549 widget->Show(); |
548 cycle_ui_widget_ = widget; | 550 cycle_ui_widget_ = widget; |
549 } | 551 } |
550 | 552 |
551 } // namespace ash | 553 } // namespace ash |
OLD | NEW |