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 |