blob: fd400d48c9a98b0dbd1827db0f5053e25b2789af [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <vector>
#include "ash/ash_export.h"
#include "ash/wm/overview/overview_animation_type.h"
#include "ash/wm/overview/overview_session.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/transform.h"
namespace aura {
class Window;
namespace ui {
class Layer;
namespace ash {
class OverviewItem;
class ScopedOverviewAnimationSettings;
class ScopedOverviewHideWindows;
// Manages a window, and its transient children, in the overview mode. This
// class allows transforming the windows with a helper to determine the best
// fit in certain bounds. The window's state is restored when this object is
// destroyed.
class ASH_EXPORT ScopedOverviewTransformWindow
: public ui::ImplicitAnimationObserver {
// Overview windows have certain properties if their aspect ratio exceedes a
// threshold. This enum keeps track of which category the window falls into,
// based on its aspect ratio.
enum class GridWindowFillMode {
kNormal = 0,
using ScopedAnimationSettings =
// Windows whose aspect ratio surpass this (width twice as large as height or
// vice versa) will be classified as too wide or too tall and will be handled
// slightly differently in overview mode.
static constexpr float kExtremeWindowRatioThreshold = 2.f;
// Calculates and returns an optimal scale ratio. This is only taking into
// account |size.height()| as the width can vary.
static float GetItemScale(const gfx::SizeF& source,
const gfx::SizeF& target,
int top_view_inset,
int title_height);
// Returns the transform turning |src_rect| into |dst_rect|.
static gfx::Transform GetTransformForRect(const gfx::RectF& src_rect,
const gfx::RectF& dst_rect);
ScopedOverviewTransformWindow(OverviewItem* overview_item,
aura::Window* window);
~ScopedOverviewTransformWindow() override;
// Starts an animation sequence which will use animation settings specified by
// |animation_type|. The |animation_settings| container is populated with
// scoped entities and the container should be destroyed at the end of the
// animation sequence.
// Example:
// ScopedOverviewTransformWindow overview_window(window);
// ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
// overview_window.BeginScopedAnimation(
// &animation_settings);
// // Calls to SetTransform & SetOpacity will use the same animation settings
// // until animation_settings is destroyed.
// overview_window.SetTransform(root_window, new_transform);
// overview_window.SetOpacity(1);
void BeginScopedAnimation(OverviewAnimationType animation_type,
ScopedAnimationSettings* animation_settings);
// Returns true if this overview window contains the |target|.
bool Contains(const aura::Window* target) const;
// Returns transformed bounds of the overview window. See
// OverviewUtil::GetTransformedBounds for more details.
gfx::RectF GetTransformedBounds() const;
// Returns the kTopViewInset property of |window_| unless there are transient
// ancestors, in which case returns 0.
int GetTopInset() const;
// Restores and animates the managed window to its non overview mode state.
// If |reset_transform| equals false, the window's transform will not be reset
// to identity transform when exiting the overview mode. See
// OverviewItem::RestoreWindow() for details why we need this.
void RestoreWindow(bool reset_transform);
// Informs the ScopedOverviewTransformWindow that the window being watched was
// destroyed. This resets the internal window pointer.
void OnWindowDestroyed();
// Prepares for overview mode by doing any necessary actions before entering.
void PrepareForOverview();
// Sets the opacity of the managed windows.
void SetOpacity(float opacity);
// Returns |rect| having been shrunk to fit within |bounds| (preserving the
// aspect ratio). Takes into account a window header that is |top_view_inset|
// tall in the original window getting replaced by a window caption that is
// |title_height| tall in the transformed window. If |type_| is not normal,
// write |overview_bounds_|, which would differ than the return bounds.
gfx::RectF ShrinkRectToFitPreservingAspectRatio(const gfx::RectF& rect,
const gfx::RectF& bounds,
int top_view_inset,
int title_height);
// Returns the window used to show the content in overview mode.
// For minimized window this will be a window that hosts mirrored layers.
aura::Window* GetOverviewWindow() const;
// Closes the transient root of the window managed by |this|.
void Close();
bool IsMinimized() const;
// Ensures that a window is visible by setting its opacity to 1.
void EnsureVisible();
// Called via OverviewItem from OverviewGrid when |window_|'s bounds
// change. Must be called before PositionWindows in OverviewGrid.
void UpdateWindowDimensionsType();
// Updates the mask which gives rounded corners on the windows. Shows the mask
// if |show| is true, otherwise removes it.
void UpdateMask(bool show);
// Stop listening to any animations to finish.
void CancelAnimationsListener();
// ui::ImplicitAnimationObserver:
void OnLayerAnimationStarted(ui::LayerAnimationSequence* sequence) override;
void OnImplicitAnimationsCompleted() override;
aura::Window* window() const { return window_; }
GridWindowFillMode type() const { return type_; }
base::Optional<gfx::RectF> overview_bounds() const {
return overview_bounds_;
gfx::Rect GetMaskBoundsForTesting() const;
friend class OverviewSessionTest;
class LayerCachingAndFilteringObserver;
class WindowMask;
// Closes the window managed by |this|.
void CloseWidget();
// Makes Close() execute synchronously when used in tests.
static void SetImmediateCloseForTests();
// A weak pointer to the overview item that owns |this|. Guaranteed to be not
// null for the lifetime of |this|.
OverviewItem* overview_item_;
// A weak pointer to the real window in the overview.
aura::Window* window_;
// True if the window has been transformed for overview mode.
bool overview_started_ = false;
// The original opacity of the window before entering overview mode.
float original_opacity_;
// For the duration of this object |window_| event targeting policy will be
// sent to NONE. Store the original so we can change it back when destroying
// this object.
ws::mojom::EventTargetingPolicy original_event_targeting_policy_;
// Specifies how the window is laid out in the grid.
GridWindowFillMode type_ = GridWindowFillMode::kNormal;
// Empty if window is of type normal. Contains the bounds the overview item
// should be if the window is too wide or too tall.
base::Optional<gfx::RectF> overview_bounds_;
// The observers associated with the layers we requested caching render
// surface and trilinear filtering. The requests will be removed in dtor if
// the layer has not been destroyed.
// A mask to be applied on |window_|. This will give |window_| rounded edges
// while in overview.
std::unique_ptr<WindowMask> mask_;
// The original mask layer of the window before entering overview mode.
ui::Layer* original_mask_layer_ = nullptr;
std::unique_ptr<ScopedOverviewHideWindows> hidden_transient_children_;
base::WeakPtrFactory<ScopedOverviewTransformWindow> weak_ptr_factory_;
} // namespace ash