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/common/wm/overview/scoped_transform_overview_window.h" | 5 #include "ash/common/wm/overview/scoped_transform_overview_window.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "ash/common/material_design/material_design_controller.h" | 10 #include "ash/common/material_design/material_design_controller.h" |
| 11 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" | 11 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" |
| 12 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" | 12 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
| 13 #include "ash/common/wm/overview/window_selector_item.h" | 13 #include "ash/common/wm/overview/window_selector_item.h" |
| 14 #include "ash/common/wm/window_state.h" | 14 #include "ash/common/wm/window_state.h" |
| 15 #include "ash/common/wm_window.h" | 15 #include "ash/common/wm_window.h" |
| 16 #include "ash/common/wm_window_property.h" | 16 #include "ash/common/wm_window_property.h" |
| 17 #include "base/macros.h" | 17 #include "base/macros.h" |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "third_party/skia/include/core/SkPaint.h" | 20 #include "third_party/skia/include/core/SkPaint.h" |
| 21 #include "third_party/skia/include/core/SkPath.h" | 21 #include "third_party/skia/include/core/SkPath.h" |
| 22 #include "third_party/skia/include/core/SkRect.h" | 22 #include "third_party/skia/include/core/SkRect.h" |
| 23 #include "ui/compositor/layer.h" | 23 #include "ui/compositor/layer.h" |
| 24 #include "ui/compositor/layer_animation_observer.h" | |
| 24 #include "ui/compositor/layer_delegate.h" | 25 #include "ui/compositor/layer_delegate.h" |
| 25 #include "ui/compositor/paint_recorder.h" | 26 #include "ui/compositor/paint_recorder.h" |
| 26 #include "ui/gfx/geometry/rect.h" | 27 #include "ui/gfx/geometry/rect.h" |
| 27 #include "ui/gfx/geometry/safe_integer_conversions.h" | 28 #include "ui/gfx/geometry/safe_integer_conversions.h" |
| 28 #include "ui/gfx/transform_util.h" | 29 #include "ui/gfx/transform_util.h" |
| 29 | 30 |
| 30 using WmWindows = std::vector<ash::WmWindow*>; | 31 using WmWindows = std::vector<ash::WmWindow*>; |
| 31 | 32 |
| 32 namespace ash { | 33 namespace ash { |
| 33 | 34 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 void ScopedTransformOverviewWindow::OverviewContentMask:: | 242 void ScopedTransformOverviewWindow::OverviewContentMask:: |
| 242 OnDeviceScaleFactorChanged(float device_scale_factor) { | 243 OnDeviceScaleFactorChanged(float device_scale_factor) { |
| 243 // Redrawing will take care of scale factor change. | 244 // Redrawing will take care of scale factor change. |
| 244 } | 245 } |
| 245 | 246 |
| 246 base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: | 247 base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: |
| 247 PrepareForLayerBoundsChange() { | 248 PrepareForLayerBoundsChange() { |
| 248 return base::Closure(); | 249 return base::Closure(); |
| 249 } | 250 } |
| 250 | 251 |
| 252 // A class that hides the original window's header and optionally sets a mask | |
| 253 // or a shape on the target to make the corners rounded. The header is hidden | |
| 254 // once the animations complete. When not animating, the changes are done | |
| 255 // immediately upon construction. | |
| 256 class ScopedTransformOverviewWindow::OverviewWindowAnimationObserver | |
| 257 : public ui::LayerAnimationObserver { | |
| 258 public: | |
| 259 OverviewWindowAnimationObserver( | |
| 260 ScopedTransformOverviewWindow* window, | |
| 261 bool animate, | |
| 262 bool use_mask, | |
| 263 bool use_shape, | |
| 264 int radius, | |
| 265 ScopedTransformOverviewWindow::OverviewContentMask* mask, | |
| 266 SkRegion* original_window_shape) | |
| 267 : window_(window), | |
| 268 animate_(animate), | |
| 269 use_mask_(use_mask), | |
| 270 use_shape_(use_shape), | |
| 271 radius_(radius), | |
| 272 mask_(mask), | |
| 273 original_window_shape_(original_window_shape) { | |
| 274 if (animate_) { | |
| 275 window_->window()->GetLayer()->GetAnimator()->AddObserver(this); | |
| 276 return; | |
| 277 } | |
| 278 HideHeaderAndSetShape(); | |
| 279 } | |
| 280 | |
| 281 ~OverviewWindowAnimationObserver() override { | |
| 282 if (animate_) | |
| 283 window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); | |
| 284 } | |
| 285 | |
| 286 // ui::LayerAnimationObserver: | |
| 287 void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override { | |
| 288 window_->window()->GetLayer()->GetAnimator()->RemoveObserver(this); | |
| 289 HideHeaderAndSetShape(); | |
| 290 } | |
| 291 | |
| 292 void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {} | |
|
bruthig
2016/08/30 17:57:33
Would it make sense to perform the same actions in
varkha
2016/09/02 11:22:50
I've reworked this and the observer now lives in w
| |
| 293 | |
| 294 void OnLayerAnimationScheduled( | |
| 295 ui::LayerAnimationSequence* sequence) override {} | |
| 296 | |
| 297 private: | |
| 298 void HideHeaderAndSetShape() { | |
| 299 gfx::Rect bounds(window_->GetTargetBoundsInScreen().size()); | |
| 300 const int inset = (use_mask_ || use_shape_) ? window_->GetTopInset() : 0; | |
| 301 if (mask_) { | |
| 302 // Mask layer is used both to hide the window header and to use rounded | |
| 303 // corners. Its layout needs to be update when setting a transform. | |
| 304 mask_->layer()->SetBounds(bounds); | |
| 305 mask_->set_inset(inset); | |
| 306 mask_->set_radius(radius_); | |
| 307 window_->window()->GetLayer()->SchedulePaint(bounds); | |
| 308 } else if (inset > 0) { | |
| 309 // Alpha shape is only used to to hide the window header and only when | |
| 310 // not using a mask layer. | |
| 311 bounds.Inset(0, inset, 0, 0); | |
| 312 SkRegion* region = new SkRegion; | |
| 313 region->setRect(RectToSkIRect(bounds)); | |
| 314 if (original_window_shape_) | |
| 315 region->op(*original_window_shape_, SkRegion::kIntersect_Op); | |
| 316 window_->window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); | |
| 317 window_->window()->SetMasksToBounds(true); | |
| 318 } | |
| 319 } | |
| 320 | |
| 321 ScopedTransformOverviewWindow* window_; | |
| 322 bool animate_; | |
| 323 bool use_mask_; | |
|
bruthig
2016/08/30 17:57:33
I find it confusing that there is a bool |use_mask
varkha
2016/09/02 11:22:51
Masks will be removed in the next CL and there wil
bruthig
2016/09/02 16:00:12
Acknowledged.
| |
| 324 bool use_shape_; | |
| 325 int radius_; | |
| 326 ScopedTransformOverviewWindow::OverviewContentMask* mask_; | |
| 327 SkRegion* original_window_shape_; | |
| 328 | |
| 329 DISALLOW_COPY_AND_ASSIGN(OverviewWindowAnimationObserver); | |
| 330 }; | |
| 331 | |
| 251 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) | 332 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) |
| 252 : window_(window), | 333 : window_(window), |
| 253 determined_original_window_shape_(false), | 334 determined_original_window_shape_(false), |
| 254 original_visibility_( | 335 original_visibility_( |
| 255 window->GetWindowState()->GetStateType() == | 336 window->GetWindowState()->GetStateType() == |
| 256 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED | 337 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED |
| 257 ? ORIGINALLY_DOCKED_MINIMIZED | 338 ? ORIGINALLY_DOCKED_MINIMIZED |
| 258 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED | 339 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED |
| 259 ? ORIGINALLY_MINIMIZED | 340 ? ORIGINALLY_MINIMIZED |
| 260 : ORIGINALLY_VISIBLE)), | 341 : ORIGINALLY_VISIBLE)), |
| 261 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), | 342 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), |
| 262 overview_started_(false), | 343 overview_started_(false), |
| 263 original_transform_(window->GetTargetTransform()), | 344 original_transform_(window->GetTargetTransform()), |
| 264 original_opacity_(window->GetTargetOpacity()), | 345 original_opacity_(window->GetTargetOpacity()), |
| 265 weak_ptr_factory_(this) {} | 346 weak_ptr_factory_(this) {} |
| 266 | 347 |
| 267 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} | 348 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} |
| 268 | 349 |
| 269 void ScopedTransformOverviewWindow::RestoreWindow() { | 350 void ScopedTransformOverviewWindow::RestoreWindow() { |
| 270 ScopedAnimationSettings animation_settings_list; | 351 ScopedAnimationSettings animation_settings_list; |
| 271 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, | 352 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
| 272 &animation_settings_list); | 353 &animation_settings_list); |
| 273 SetTransform(window()->GetRootWindow(), original_transform_, | 354 SetTransform(window()->GetRootWindow(), original_transform_, |
| 274 false /* use_mask */, false /* use_shape */, 0); | 355 false /* use_mask */, false /* use_shape */, 0, |
| 356 true /* animate */); | |
| 275 | 357 |
| 276 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 358 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
| 277 CreateScopedOverviewAnimationSettings( | 359 CreateScopedOverviewAnimationSettings( |
| 278 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | 360 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
| 279 window_); | 361 window_); |
| 280 gfx::Transform transform; | 362 gfx::Transform transform; |
| 281 if ((original_visibility_ == ORIGINALLY_MINIMIZED && | 363 if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
| 282 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || | 364 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || |
| 283 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && | 365 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
| 284 window_->GetWindowState()->GetStateType() != | 366 window_->GetWindowState()->GetStateType() != |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 338 continue; | 420 continue; |
| 339 } | 421 } |
| 340 bounds.Union( | 422 bounds.Union( |
| 341 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); | 423 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); |
| 342 } | 424 } |
| 343 return bounds; | 425 return bounds; |
| 344 } | 426 } |
| 345 | 427 |
| 346 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( | 428 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( |
| 347 bool hide_header) const { | 429 bool hide_header) const { |
| 430 if (window_->GetWindowState()->IsMinimized()) | |
| 431 return window_->GetMinimizeAnimationTargetBoundsInScreen(); | |
| 432 | |
| 348 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 433 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); |
| 349 const int top_inset = hide_header ? GetTopInset() : 0; | 434 const int top_inset = hide_header ? GetTopInset() : 0; |
| 350 gfx::Rect bounds; | 435 gfx::Rect bounds; |
| 351 for (auto* window : GetTransientTreeIterator(window_)) { | 436 for (auto* window : GetTransientTreeIterator(window_)) { |
| 352 // Ignore other window types when computing bounding box of window | 437 // Ignore other window types when computing bounding box of window |
| 353 // selector target item. | 438 // selector target item. |
| 354 if (window != window_ && | 439 if (window != window_ && |
| 355 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && | 440 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| 356 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { | 441 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { |
| 357 continue; | 442 continue; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 461 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), | 546 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), |
| 462 static_cast<float>(dst_rect.height()) / src_rect.height()); | 547 static_cast<float>(dst_rect.height()) / src_rect.height()); |
| 463 return transform; | 548 return transform; |
| 464 } | 549 } |
| 465 | 550 |
| 466 void ScopedTransformOverviewWindow::SetTransform( | 551 void ScopedTransformOverviewWindow::SetTransform( |
| 467 WmWindow* root_window, | 552 WmWindow* root_window, |
| 468 const gfx::Transform& transform, | 553 const gfx::Transform& transform, |
| 469 bool use_mask, | 554 bool use_mask, |
| 470 bool use_shape, | 555 bool use_shape, |
| 471 float radius) { | 556 float radius, |
| 557 bool animate) { | |
| 472 DCHECK(overview_started_); | 558 DCHECK(overview_started_); |
| 473 | 559 |
| 474 if (ash::MaterialDesignController::IsOverviewMaterial() && | 560 if (ash::MaterialDesignController::IsOverviewMaterial() && |
| 475 &transform != &original_transform_) { | 561 &transform != &original_transform_) { |
| 476 if (use_mask && !mask_) { | 562 if (use_mask && !mask_) { |
| 477 mask_.reset(new OverviewContentMask()); | 563 mask_.reset(new OverviewContentMask()); |
| 478 mask_->layer()->SetFillsBoundsOpaquely(false); | 564 mask_->layer()->SetFillsBoundsOpaquely(false); |
| 479 window()->GetLayer()->SetMaskLayer(mask_->layer()); | 565 window()->GetLayer()->SetMaskLayer(mask_->layer()); |
| 480 } | 566 } |
| 481 if (!determined_original_window_shape_) { | 567 if (!determined_original_window_shape_) { |
| 482 determined_original_window_shape_ = true; | 568 determined_original_window_shape_ = true; |
| 483 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); | 569 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); |
| 484 if (!original_window_shape_ && window_shape) | 570 if (!original_window_shape_ && window_shape) |
| 485 original_window_shape_.reset(new SkRegion(*window_shape)); | 571 original_window_shape_.reset(new SkRegion(*window_shape)); |
| 486 } | 572 } |
| 487 gfx::Rect bounds(GetTargetBoundsInScreen().size()); | 573 animation_observer_.reset(new OverviewWindowAnimationObserver( |
| 488 const int inset = (use_mask || use_shape) ? GetTopInset() : 0; | 574 this, animate, use_mask, use_shape, radius, mask_.get(), |
| 489 if (mask_) { | 575 original_window_shape_.get())); |
| 490 // Mask layer is used both to hide the window header and to use rounded | |
| 491 // corners. Its layout needs to be update when setting a transform. | |
| 492 mask_->layer()->SetBounds(bounds); | |
| 493 mask_->set_inset(inset); | |
| 494 mask_->set_radius(radius); | |
| 495 window()->GetLayer()->SchedulePaint(bounds); | |
| 496 } else if (inset > 0) { | |
| 497 // Alpha shape is only used to to hide the window header and only when | |
| 498 // not using a mask layer. | |
| 499 bounds.Inset(0, inset, 0, 0); | |
| 500 SkRegion* region = new SkRegion; | |
| 501 region->setRect(RectToSkIRect(bounds)); | |
| 502 if (original_window_shape_) | |
| 503 region->op(*original_window_shape_, SkRegion::kIntersect_Op); | |
| 504 window()->GetLayer()->SetAlphaShape(base::WrapUnique(region)); | |
| 505 window()->SetMasksToBounds(true); | |
| 506 } | |
| 507 } | 576 } |
| 508 | 577 |
| 509 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); | 578 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |
| 510 | 579 |
| 511 for (auto* window : GetTransientTreeIterator(window_)) { | 580 for (auto* window : GetTransientTreeIterator(window_)) { |
| 512 WmWindow* parent_window = window->GetParent(); | 581 WmWindow* parent_window = window->GetParent(); |
| 513 gfx::Point original_origin = | 582 gfx::Point original_origin = |
| 514 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); | 583 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); |
| 515 gfx::Transform new_transform = | 584 gfx::Transform new_transform = |
| 516 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), | 585 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 if (parent_window) | 619 if (parent_window) |
| 551 parent_window->CloseWidget(); | 620 parent_window->CloseWidget(); |
| 552 } | 621 } |
| 553 | 622 |
| 554 // static | 623 // static |
| 555 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { | 624 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { |
| 556 immediate_close_for_tests = true; | 625 immediate_close_for_tests = true; |
| 557 } | 626 } |
| 558 | 627 |
| 559 } // namespace ash | 628 } // namespace ash |
| OLD | NEW |