| 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" | |
| 11 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" | 10 #include "ash/common/wm/overview/scoped_overview_animation_settings.h" |
| 12 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" | 11 #include "ash/common/wm/overview/scoped_overview_animation_settings_factory.h" |
| 13 #include "ash/common/wm/overview/window_selector_item.h" | 12 #include "ash/common/wm/overview/window_selector_item.h" |
| 14 #include "ash/common/wm/window_state.h" | 13 #include "ash/common/wm/window_state.h" |
| 15 #include "ash/common/wm_window.h" | 14 #include "ash/common/wm_window.h" |
| 16 #include "ash/common/wm_window_property.h" | 15 #include "ash/common/wm_window_property.h" |
| 17 #include "base/macros.h" | 16 #include "base/macros.h" |
| 18 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "third_party/skia/include/core/SkPaint.h" | 19 #include "third_party/skia/include/core/SkPaint.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 32 namespace ash { | 31 namespace ash { |
| 33 | 32 |
| 34 namespace { | 33 namespace { |
| 35 | 34 |
| 36 // When set to true by tests makes closing the widget synchronous. | 35 // When set to true by tests makes closing the widget synchronous. |
| 37 bool immediate_close_for_tests = false; | 36 bool immediate_close_for_tests = false; |
| 38 | 37 |
| 39 // The opacity level that windows will be set to when they are restored. | 38 // The opacity level that windows will be set to when they are restored. |
| 40 const float kRestoreWindowOpacity = 1.0f; | 39 const float kRestoreWindowOpacity = 1.0f; |
| 41 | 40 |
| 42 // Alpha value used to paint mask layer that masks the original window header. | 41 // Delay closing window to allow it to shrink and fade out. |
| 43 const int kOverviewContentMaskAlpha = 255; | |
| 44 | |
| 45 // Delay closing window with Material Design to allow it to shrink and fade out. | |
| 46 const int kCloseWindowDelayInMilliseconds = 150; | 42 const int kCloseWindowDelayInMilliseconds = 150; |
| 47 | 43 |
| 48 WmWindow* GetTransientRoot(WmWindow* window) { | 44 WmWindow* GetTransientRoot(WmWindow* window) { |
| 49 while (window && window->GetTransientParent()) | 45 while (window && window->GetTransientParent()) |
| 50 window = window->GetTransientParent(); | 46 window = window->GetTransientParent(); |
| 51 return window; | 47 return window; |
| 52 } | 48 } |
| 53 | 49 |
| 54 std::unique_ptr<ScopedOverviewAnimationSettings> | 50 std::unique_ptr<ScopedOverviewAnimationSettings> |
| 55 CreateScopedOverviewAnimationSettings(OverviewAnimationType animation_type, | 51 CreateScopedOverviewAnimationSettings(OverviewAnimationType animation_type, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 const TransientDescendantIterator& begin) | 164 const TransientDescendantIterator& begin) |
| 169 : begin_(begin) {} | 165 : begin_(begin) {} |
| 170 | 166 |
| 171 TransientDescendantIteratorRange GetTransientTreeIterator(WmWindow* window) { | 167 TransientDescendantIteratorRange GetTransientTreeIterator(WmWindow* window) { |
| 172 return TransientDescendantIteratorRange( | 168 return TransientDescendantIteratorRange( |
| 173 TransientDescendantIterator(GetTransientRoot(window))); | 169 TransientDescendantIterator(GetTransientRoot(window))); |
| 174 } | 170 } |
| 175 | 171 |
| 176 } // namespace | 172 } // namespace |
| 177 | 173 |
| 178 // Mask layer that clips the window's original header in overview mode. | |
| 179 // Only used with Material Design. | |
| 180 class ScopedTransformOverviewWindow::OverviewContentMask | |
| 181 : public ui::LayerDelegate { | |
| 182 public: | |
| 183 explicit OverviewContentMask(); | |
| 184 ~OverviewContentMask() override; | |
| 185 | |
| 186 void set_radius(float radius) { radius_ = radius; } | |
| 187 void set_inset(int inset) { inset_ = inset; } | |
| 188 ui::Layer* layer() { return &layer_; } | |
| 189 | |
| 190 // Overridden from LayerDelegate. | |
| 191 void OnPaintLayer(const ui::PaintContext& context) override; | |
| 192 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {} | |
| 193 void OnDeviceScaleFactorChanged(float device_scale_factor) override; | |
| 194 base::Closure PrepareForLayerBoundsChange() override; | |
| 195 | |
| 196 private: | |
| 197 ui::Layer layer_; | |
| 198 float radius_; | |
| 199 int inset_; | |
| 200 | |
| 201 DISALLOW_COPY_AND_ASSIGN(OverviewContentMask); | |
| 202 }; | |
| 203 | |
| 204 ScopedTransformOverviewWindow::OverviewContentMask::OverviewContentMask() | |
| 205 : layer_(ui::LAYER_TEXTURED), radius_(0), inset_(0) { | |
| 206 layer_.set_delegate(this); | |
| 207 } | |
| 208 | |
| 209 ScopedTransformOverviewWindow::OverviewContentMask::~OverviewContentMask() { | |
| 210 layer_.set_delegate(nullptr); | |
| 211 } | |
| 212 | |
| 213 void ScopedTransformOverviewWindow::OverviewContentMask::OnPaintLayer( | |
| 214 const ui::PaintContext& context) { | |
| 215 ui::PaintRecorder recorder(context, layer()->size()); | |
| 216 gfx::Rect bounds(layer()->bounds().size()); | |
| 217 bounds.Inset(0, inset_, 0, 0); | |
| 218 | |
| 219 // Tile a window into an area, rounding the bottom corners. | |
| 220 const SkRect rect = gfx::RectToSkRect(bounds); | |
| 221 const SkScalar corner_radius_scalar = SkIntToScalar(radius_); | |
| 222 SkScalar radii[8] = {0, | |
| 223 0, // top-left | |
| 224 0, | |
| 225 0, // top-right | |
| 226 corner_radius_scalar, | |
| 227 corner_radius_scalar, // bottom-right | |
| 228 corner_radius_scalar, | |
| 229 corner_radius_scalar}; // bottom-left | |
| 230 SkPath path; | |
| 231 path.addRoundRect(rect, radii, SkPath::kCW_Direction); | |
| 232 | |
| 233 // Set a mask. | |
| 234 SkPaint paint; | |
| 235 paint.setAlpha(kOverviewContentMaskAlpha); | |
| 236 paint.setStyle(SkPaint::kFill_Style); | |
| 237 paint.setAntiAlias(true); | |
| 238 recorder.canvas()->DrawPath(path, paint); | |
| 239 } | |
| 240 | |
| 241 void ScopedTransformOverviewWindow::OverviewContentMask:: | |
| 242 OnDeviceScaleFactorChanged(float device_scale_factor) { | |
| 243 // Redrawing will take care of scale factor change. | |
| 244 } | |
| 245 | |
| 246 base::Closure ScopedTransformOverviewWindow::OverviewContentMask:: | |
| 247 PrepareForLayerBoundsChange() { | |
| 248 return base::Closure(); | |
| 249 } | |
| 250 | |
| 251 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) | 174 ScopedTransformOverviewWindow::ScopedTransformOverviewWindow(WmWindow* window) |
| 252 : window_(window), | 175 : window_(window), |
| 253 determined_original_window_shape_(false), | 176 determined_original_window_shape_(false), |
| 254 original_visibility_( | 177 original_visibility_( |
| 255 window->GetWindowState()->GetStateType() == | 178 window->GetWindowState()->GetStateType() == |
| 256 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED | 179 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED |
| 257 ? ORIGINALLY_DOCKED_MINIMIZED | 180 ? ORIGINALLY_DOCKED_MINIMIZED |
| 258 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED | 181 : (window->GetShowState() == ui::SHOW_STATE_MINIMIZED |
| 259 ? ORIGINALLY_MINIMIZED | 182 ? ORIGINALLY_MINIMIZED |
| 260 : ORIGINALLY_VISIBLE)), | 183 : ORIGINALLY_VISIBLE)), |
| 261 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), | 184 ignored_by_shelf_(window->GetWindowState()->ignored_by_shelf()), |
| 262 overview_started_(false), | 185 overview_started_(false), |
| 263 original_transform_(window->GetTargetTransform()), | 186 original_transform_(window->GetTargetTransform()), |
| 264 original_opacity_(window->GetTargetOpacity()), | 187 original_opacity_(window->GetTargetOpacity()), |
| 265 weak_ptr_factory_(this) {} | 188 weak_ptr_factory_(this) {} |
| 266 | 189 |
| 267 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} | 190 ScopedTransformOverviewWindow::~ScopedTransformOverviewWindow() {} |
| 268 | 191 |
| 269 void ScopedTransformOverviewWindow::RestoreWindow() { | 192 void ScopedTransformOverviewWindow::RestoreWindow() { |
| 270 ScopedAnimationSettings animation_settings_list; | 193 ScopedAnimationSettings animation_settings_list; |
| 271 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, | 194 BeginScopedAnimation(OverviewAnimationType::OVERVIEW_ANIMATION_RESTORE_WINDOW, |
| 272 &animation_settings_list); | 195 &animation_settings_list); |
| 273 SetTransform(window()->GetRootWindow(), original_transform_, | 196 SetTransform(window()->GetRootWindow(), original_transform_); |
| 274 false /* use_mask */); | |
| 275 set_overview_transform(original_transform_); | 197 set_overview_transform(original_transform_); |
| 276 | 198 |
| 277 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = | 199 std::unique_ptr<ScopedOverviewAnimationSettings> animation_settings = |
| 278 CreateScopedOverviewAnimationSettings( | 200 CreateScopedOverviewAnimationSettings( |
| 279 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, | 201 OverviewAnimationType::OVERVIEW_ANIMATION_LAY_OUT_SELECTOR_ITEMS, |
| 280 window_); | 202 window_); |
| 281 gfx::Transform transform; | 203 gfx::Transform transform; |
| 282 if ((original_visibility_ == ORIGINALLY_MINIMIZED && | 204 if ((original_visibility_ == ORIGINALLY_MINIMIZED && |
| 283 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || | 205 window_->GetShowState() != ui::SHOW_STATE_MINIMIZED) || |
| 284 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && | 206 (original_visibility_ == ORIGINALLY_DOCKED_MINIMIZED && |
| 285 window_->GetWindowState()->GetStateType() != | 207 window_->GetWindowState()->GetStateType() != |
| 286 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { | 208 wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED)) { |
| 287 // Setting opacity 0 and visible false ensures that the property change | 209 // Setting opacity 0 and visible false ensures that the property change |
| 288 // to SHOW_STATE_MINIMIZED will not animate the window from its original | 210 // to SHOW_STATE_MINIMIZED will not animate the window from its original |
| 289 // bounds to the minimized position. | 211 // bounds to the minimized position. |
| 290 // Hiding the window needs to be done before the target opacity is 0, | 212 // Hiding the window needs to be done before the target opacity is 0, |
| 291 // otherwise the layer's visibility will not be updated | 213 // otherwise the layer's visibility will not be updated |
| 292 // (See VisibilityController::UpdateLayerVisibility). | 214 // (See VisibilityController::UpdateLayerVisibility). |
| 293 window_->Hide(); | 215 window_->Hide(); |
| 294 window_->SetOpacity(0); | 216 window_->SetOpacity(0); |
| 295 window_->SetShowState(ui::SHOW_STATE_MINIMIZED); | 217 window_->SetShowState(ui::SHOW_STATE_MINIMIZED); |
| 296 } | 218 } |
| 297 window_->GetWindowState()->set_ignored_by_shelf(ignored_by_shelf_); | 219 window_->GetWindowState()->set_ignored_by_shelf(ignored_by_shelf_); |
| 298 SetOpacity(original_opacity_); | 220 SetOpacity(original_opacity_); |
| 299 | 221 ShowHeaderAndResetShape(); |
| 300 if (ash::MaterialDesignController::IsOverviewMaterial()) | |
| 301 ShowHeaderAndResetShape(); | |
| 302 } | 222 } |
| 303 | 223 |
| 304 void ScopedTransformOverviewWindow::BeginScopedAnimation( | 224 void ScopedTransformOverviewWindow::BeginScopedAnimation( |
| 305 OverviewAnimationType animation_type, | 225 OverviewAnimationType animation_type, |
| 306 ScopedAnimationSettings* animation_settings) { | 226 ScopedAnimationSettings* animation_settings) { |
| 307 for (auto* window : GetTransientTreeIterator(window_)) { | 227 for (auto* window : GetTransientTreeIterator(window_)) { |
| 308 animation_settings->push_back( | 228 animation_settings->push_back( |
| 309 CreateScopedOverviewAnimationSettings(animation_type, window)); | 229 CreateScopedOverviewAnimationSettings(animation_type, window)); |
| 310 } | 230 } |
| 311 } | 231 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 326 if (window != window_ && window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && | 246 if (window != window_ && window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| 327 window->GetType() != ui::wm::WINDOW_TYPE_PANEL) { | 247 window->GetType() != ui::wm::WINDOW_TYPE_PANEL) { |
| 328 continue; | 248 continue; |
| 329 } | 249 } |
| 330 bounds.Union( | 250 bounds.Union( |
| 331 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); | 251 window->GetParent()->ConvertRectToScreen(window->GetTargetBounds())); |
| 332 } | 252 } |
| 333 return bounds; | 253 return bounds; |
| 334 } | 254 } |
| 335 | 255 |
| 336 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds( | 256 gfx::Rect ScopedTransformOverviewWindow::GetTransformedBounds() const { |
| 337 bool hide_header) const { | |
| 338 if (window_->GetWindowState()->IsMinimized()) | 257 if (window_->GetWindowState()->IsMinimized()) |
| 339 return window_->GetMinimizeAnimationTargetBoundsInScreen(); | 258 return window_->GetMinimizeAnimationTargetBoundsInScreen(); |
| 340 | 259 |
| 341 const bool material = ash::MaterialDesignController::IsOverviewMaterial(); | 260 const int top_inset = GetTopInset(); |
| 342 const int top_inset = hide_header ? GetTopInset() : 0; | |
| 343 gfx::Rect bounds; | 261 gfx::Rect bounds; |
| 344 for (auto* window : GetTransientTreeIterator(window_)) { | 262 for (auto* window : GetTransientTreeIterator(window_)) { |
| 345 // Ignore other window types when computing bounding box of window | 263 // Ignore other window types when computing bounding box of window |
| 346 // selector target item. | 264 // selector target item. |
| 347 if (window != window_ && | 265 if (window != window_ && (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && |
| 348 (!material || (window->GetType() != ui::wm::WINDOW_TYPE_NORMAL && | 266 window->GetType() != ui::wm::WINDOW_TYPE_PANEL)) { |
| 349 window->GetType() != ui::wm::WINDOW_TYPE_PANEL))) { | |
| 350 continue; | 267 continue; |
| 351 } | 268 } |
| 352 gfx::RectF window_bounds(window->GetTargetBounds()); | 269 gfx::RectF window_bounds(window->GetTargetBounds()); |
| 353 gfx::Transform new_transform = | 270 gfx::Transform new_transform = |
| 354 TransformAboutPivot(gfx::Point(window_bounds.x(), window_bounds.y()), | 271 TransformAboutPivot(gfx::Point(window_bounds.x(), window_bounds.y()), |
| 355 window->GetTargetTransform()); | 272 window->GetTargetTransform()); |
| 356 new_transform.TransformRect(&window_bounds); | 273 new_transform.TransformRect(&window_bounds); |
| 357 | 274 |
| 358 // With Material Design the preview title is shown above the preview window. | 275 // The preview title is shown above the preview window. Hide the window |
| 359 // Hide the window header for apps or browser windows with no tabs (web | 276 // header for apps or browser windows with no tabs (web apps) to avoid |
| 360 // apps) to avoid showing both the window header and the preview title. | 277 // showing both the window header and the preview title. |
| 361 if (material && top_inset > 0) { | 278 if (top_inset > 0) { |
| 362 gfx::RectF header_bounds(window_bounds); | 279 gfx::RectF header_bounds(window_bounds); |
| 363 header_bounds.set_height(top_inset); | 280 header_bounds.set_height(top_inset); |
| 364 new_transform.TransformRect(&header_bounds); | 281 new_transform.TransformRect(&header_bounds); |
| 365 window_bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0); | 282 window_bounds.Inset(0, gfx::ToCeiledInt(header_bounds.height()), 0, 0); |
| 366 } | 283 } |
| 367 bounds.Union(window->GetParent()->ConvertRectToScreen( | 284 bounds.Union(window->GetParent()->ConvertRectToScreen( |
| 368 ToEnclosingRect(window_bounds))); | 285 ToEnclosingRect(window_bounds))); |
| 369 } | 286 } |
| 370 return bounds; | 287 return bounds; |
| 371 } | 288 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 } | 330 } |
| 414 | 331 |
| 415 void ScopedTransformOverviewWindow::OnWindowDestroyed() { | 332 void ScopedTransformOverviewWindow::OnWindowDestroyed() { |
| 416 window_ = nullptr; | 333 window_ = nullptr; |
| 417 } | 334 } |
| 418 | 335 |
| 419 float ScopedTransformOverviewWindow::GetItemScale(const gfx::Size& source, | 336 float ScopedTransformOverviewWindow::GetItemScale(const gfx::Size& source, |
| 420 const gfx::Size& target, | 337 const gfx::Size& target, |
| 421 int top_view_inset, | 338 int top_view_inset, |
| 422 int title_height) { | 339 int title_height) { |
| 423 if (ash::MaterialDesignController::IsOverviewMaterial()) { | 340 return std::min(2.0f, static_cast<float>((target.height() - title_height)) / |
| 424 return std::min(2.0f, static_cast<float>((target.height() - title_height)) / | 341 (source.height() - top_view_inset)); |
| 425 (source.height() - top_view_inset)); | |
| 426 } | |
| 427 return std::min( | |
| 428 1.0f, std::min(static_cast<float>(target.width()) / source.width(), | |
| 429 static_cast<float>(target.height()) / source.height())); | |
| 430 } | 342 } |
| 431 | 343 |
| 432 gfx::Rect ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( | 344 gfx::Rect ScopedTransformOverviewWindow::ShrinkRectToFitPreservingAspectRatio( |
| 433 const gfx::Rect& rect, | 345 const gfx::Rect& rect, |
| 434 const gfx::Rect& bounds, | 346 const gfx::Rect& bounds, |
| 435 int top_view_inset, | 347 int top_view_inset, |
| 436 int title_height) { | 348 int title_height) { |
| 437 DCHECK(!rect.IsEmpty()); | 349 DCHECK(!rect.IsEmpty()); |
| 438 DCHECK_LE(top_view_inset, rect.height()); | 350 DCHECK_LE(top_view_inset, rect.height()); |
| 439 const float scale = | 351 const float scale = |
| 440 GetItemScale(rect.size(), bounds.size(), top_view_inset, title_height); | 352 GetItemScale(rect.size(), bounds.size(), top_view_inset, title_height); |
| 441 if (!ash::MaterialDesignController::IsOverviewMaterial()) { | |
| 442 return gfx::Rect( | |
| 443 bounds.x() + 0.5 * (bounds.width() - scale * rect.width()), | |
| 444 bounds.y() + title_height - scale * top_view_inset + | |
| 445 0.5 * (bounds.height() - | |
| 446 (title_height + scale * (rect.height() - top_view_inset))), | |
| 447 rect.width() * scale, rect.height() * scale); | |
| 448 } | |
| 449 const int horizontal_offset = gfx::ToFlooredInt( | 353 const int horizontal_offset = gfx::ToFlooredInt( |
| 450 0.5 * (bounds.width() - gfx::ToFlooredInt(scale * rect.width()))); | 354 0.5 * (bounds.width() - gfx::ToFlooredInt(scale * rect.width()))); |
| 451 const int width = bounds.width() - 2 * horizontal_offset; | 355 const int width = bounds.width() - 2 * horizontal_offset; |
| 452 const int vertical_offset = | 356 const int vertical_offset = |
| 453 title_height - gfx::ToCeiledInt(scale * top_view_inset); | 357 title_height - gfx::ToCeiledInt(scale * top_view_inset); |
| 454 const int height = std::min(gfx::ToCeiledInt(scale * rect.height()), | 358 const int height = std::min(gfx::ToCeiledInt(scale * rect.height()), |
| 455 bounds.height() - vertical_offset); | 359 bounds.height() - vertical_offset); |
| 456 return gfx::Rect(bounds.x() + horizontal_offset, bounds.y() + vertical_offset, | 360 return gfx::Rect(bounds.x() + horizontal_offset, bounds.y() + vertical_offset, |
| 457 width, height); | 361 width, height); |
| 458 } | 362 } |
| 459 | 363 |
| 460 gfx::Transform ScopedTransformOverviewWindow::GetTransformForRect( | 364 gfx::Transform ScopedTransformOverviewWindow::GetTransformForRect( |
| 461 const gfx::Rect& src_rect, | 365 const gfx::Rect& src_rect, |
| 462 const gfx::Rect& dst_rect) { | 366 const gfx::Rect& dst_rect) { |
| 463 DCHECK(!src_rect.IsEmpty()); | 367 DCHECK(!src_rect.IsEmpty()); |
| 464 gfx::Transform transform; | 368 gfx::Transform transform; |
| 465 transform.Translate(dst_rect.x() - src_rect.x(), dst_rect.y() - src_rect.y()); | 369 transform.Translate(dst_rect.x() - src_rect.x(), dst_rect.y() - src_rect.y()); |
| 466 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), | 370 transform.Scale(static_cast<float>(dst_rect.width()) / src_rect.width(), |
| 467 static_cast<float>(dst_rect.height()) / src_rect.height()); | 371 static_cast<float>(dst_rect.height()) / src_rect.height()); |
| 468 return transform; | 372 return transform; |
| 469 } | 373 } |
| 470 | 374 |
| 471 void ScopedTransformOverviewWindow::SetTransform( | 375 void ScopedTransformOverviewWindow::SetTransform( |
| 472 WmWindow* root_window, | 376 WmWindow* root_window, |
| 473 const gfx::Transform& transform, | 377 const gfx::Transform& transform) { |
| 474 bool use_mask) { | |
| 475 DCHECK(overview_started_); | 378 DCHECK(overview_started_); |
| 476 | 379 |
| 477 if (ash::MaterialDesignController::IsOverviewMaterial() && | 380 if (&transform != &original_transform_ && |
| 478 &transform != &original_transform_) { | 381 !determined_original_window_shape_) { |
| 479 if (use_mask && !mask_) { | 382 determined_original_window_shape_ = true; |
| 480 mask_.reset(new OverviewContentMask()); | 383 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); |
| 481 mask_->layer()->SetFillsBoundsOpaquely(false); | 384 if (!original_window_shape_ && window_shape) |
| 482 window()->GetLayer()->SetMaskLayer(mask_->layer()); | 385 original_window_shape_.reset(new SkRegion(*window_shape)); |
| 483 } | |
| 484 if (!determined_original_window_shape_) { | |
| 485 determined_original_window_shape_ = true; | |
| 486 SkRegion* window_shape = window()->GetLayer()->alpha_shape(); | |
| 487 if (!original_window_shape_ && window_shape) | |
| 488 original_window_shape_.reset(new SkRegion(*window_shape)); | |
| 489 } | |
| 490 } | 386 } |
| 491 | 387 |
| 492 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); | 388 gfx::Point target_origin(GetTargetBoundsInScreen().origin()); |
| 493 | 389 |
| 494 for (auto* window : GetTransientTreeIterator(window_)) { | 390 for (auto* window : GetTransientTreeIterator(window_)) { |
| 495 WmWindow* parent_window = window->GetParent(); | 391 WmWindow* parent_window = window->GetParent(); |
| 496 gfx::Point original_origin = | 392 gfx::Point original_origin = |
| 497 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); | 393 parent_window->ConvertRectToScreen(window->GetTargetBounds()).origin(); |
| 498 gfx::Transform new_transform = | 394 gfx::Transform new_transform = |
| 499 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), | 395 TransformAboutPivot(gfx::Point(target_origin.x() - original_origin.x(), |
| 500 target_origin.y() - original_origin.y()), | 396 target_origin.y() - original_origin.y()), |
| 501 transform); | 397 transform); |
| 502 window->SetTransform(new_transform); | 398 window->SetTransform(new_transform); |
| 503 } | 399 } |
| 504 } | 400 } |
| 505 | 401 |
| 506 void ScopedTransformOverviewWindow::SetOpacity(float opacity) { | 402 void ScopedTransformOverviewWindow::SetOpacity(float opacity) { |
| 507 for (auto* window : GetTransientTreeIterator(window_)) { | 403 for (auto* window : GetTransientTreeIterator(window_)) { |
| 508 window->SetOpacity(opacity); | 404 window->SetOpacity(opacity); |
| 509 } | 405 } |
| 510 } | 406 } |
| 511 | 407 |
| 512 void ScopedTransformOverviewWindow::HideHeaderAndSetShape(bool use_mask, | 408 void ScopedTransformOverviewWindow::HideHeaderAndSetShape(int radius) { |
| 513 bool use_shape, | |
| 514 int radius) { | |
| 515 gfx::Rect bounds(GetTargetBoundsInScreen().size()); | 409 gfx::Rect bounds(GetTargetBoundsInScreen().size()); |
| 516 const int inset = (use_mask || use_shape) ? GetTopInset() : 0; | 410 const int inset = GetTopInset(); |
| 517 if (mask_) { | 411 if (inset > 0) { |
| 518 // Mask layer is used both to hide the window header and to use rounded | 412 // Use alpha shape to hide the window header. |
| 519 // corners. Its layout needs to be updated when setting a transform. | |
| 520 mask_->layer()->SetBounds(bounds); | |
| 521 mask_->set_inset(inset); | |
| 522 mask_->set_radius(radius); | |
| 523 window()->GetLayer()->SchedulePaint(bounds); | |
| 524 } else if (inset > 0) { | |
| 525 // Alpha shape is only used to hide the window header and only when not | |
| 526 // using a mask layer. | |
| 527 bounds.Inset(0, inset, 0, 0); | 413 bounds.Inset(0, inset, 0, 0); |
| 528 std::unique_ptr<SkRegion> region(new SkRegion); | 414 std::unique_ptr<SkRegion> region(new SkRegion); |
| 529 region->setRect(RectToSkIRect(bounds)); | 415 region->setRect(RectToSkIRect(bounds)); |
| 530 if (original_window_shape_) | 416 if (original_window_shape_) |
| 531 region->op(*original_window_shape_, SkRegion::kIntersect_Op); | 417 region->op(*original_window_shape_, SkRegion::kIntersect_Op); |
| 532 window()->GetLayer()->SetAlphaShape(std::move(region)); | 418 window()->GetLayer()->SetAlphaShape(std::move(region)); |
| 533 window()->SetMasksToBounds(true); | 419 window()->SetMasksToBounds(true); |
| 534 } | 420 } |
| 535 } | 421 } |
| 536 | 422 |
| 537 void ScopedTransformOverviewWindow::ShowHeaderAndResetShape() { | 423 void ScopedTransformOverviewWindow::ShowHeaderAndResetShape() { |
| 538 ui::Layer* layer = window()->GetLayer(); | 424 ui::Layer* layer = window()->GetLayer(); |
| 539 layer->SetMaskLayer(nullptr); | |
| 540 mask_.reset(); | |
| 541 | |
| 542 if (original_window_shape_) { | 425 if (original_window_shape_) { |
| 543 layer->SetAlphaShape( | 426 layer->SetAlphaShape( |
| 544 base::MakeUnique<SkRegion>(*original_window_shape_.get())); | 427 base::MakeUnique<SkRegion>(*original_window_shape_.get())); |
| 545 } else { | 428 } else { |
| 546 layer->SetAlphaShape(nullptr); | 429 layer->SetAlphaShape(nullptr); |
| 547 } | 430 } |
| 548 window()->SetMasksToBounds(false); | 431 window()->SetMasksToBounds(false); |
| 549 } | 432 } |
| 550 | 433 |
| 551 void ScopedTransformOverviewWindow::Close() { | 434 void ScopedTransformOverviewWindow::Close() { |
| 552 if (immediate_close_for_tests || | 435 if (immediate_close_for_tests) { |
| 553 !ash::MaterialDesignController::IsOverviewMaterial()) { | |
| 554 CloseWidget(); | 436 CloseWidget(); |
| 555 return; | 437 return; |
| 556 } | 438 } |
| 557 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 439 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 558 FROM_HERE, base::Bind(&ScopedTransformOverviewWindow::CloseWidget, | 440 FROM_HERE, base::Bind(&ScopedTransformOverviewWindow::CloseWidget, |
| 559 weak_ptr_factory_.GetWeakPtr()), | 441 weak_ptr_factory_.GetWeakPtr()), |
| 560 base::TimeDelta::FromMilliseconds(kCloseWindowDelayInMilliseconds)); | 442 base::TimeDelta::FromMilliseconds(kCloseWindowDelayInMilliseconds)); |
| 561 } | 443 } |
| 562 | 444 |
| 563 void ScopedTransformOverviewWindow::PrepareForOverview() { | 445 void ScopedTransformOverviewWindow::PrepareForOverview() { |
| 564 DCHECK(!overview_started_); | 446 DCHECK(!overview_started_); |
| 565 overview_started_ = true; | 447 overview_started_ = true; |
| 566 window_->GetWindowState()->set_ignored_by_shelf(true); | 448 window_->GetWindowState()->set_ignored_by_shelf(true); |
| 567 ShowWindowIfMinimized(); | 449 ShowWindowIfMinimized(); |
| 568 } | 450 } |
| 569 | 451 |
| 570 void ScopedTransformOverviewWindow::CloseWidget() { | 452 void ScopedTransformOverviewWindow::CloseWidget() { |
| 571 WmWindow* parent_window = GetTransientRoot(window_); | 453 WmWindow* parent_window = GetTransientRoot(window_); |
| 572 if (parent_window) | 454 if (parent_window) |
| 573 parent_window->CloseWidget(); | 455 parent_window->CloseWidget(); |
| 574 } | 456 } |
| 575 | 457 |
| 576 // static | 458 // static |
| 577 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { | 459 void ScopedTransformOverviewWindow::SetImmediateCloseForTests() { |
| 578 immediate_close_for_tests = true; | 460 immediate_close_for_tests = true; |
| 579 } | 461 } |
| 580 | 462 |
| 581 } // namespace ash | 463 } // namespace ash |
| OLD | NEW |