1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230

ash / wm / overview / scoped_overview_transform_window.h [blame]

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_
#define ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_

#include <memory>
#include <vector>

#include "ash/ash_export.h"
#include "ash/wm/overview/overview_session.h"
#include "ash/wm/overview/overview_types.h"
#include "ash/wm/raster_scale/raster_scale_layer_observer.h"
#include "ash/wm/scoped_layer_tree_synchronizer.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/aura/client/transient_window_client_observer.h"
#include "ui/aura/window_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/transform.h"

namespace aura {
class ScopedWindowEventTargetingBlocker;
class Window;
}  // namespace aura

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 aura::client::TransientWindowClientObserver,
      public aura::WindowObserver {
 public:
  using ScopedAnimationSettings =
      std::vector<std::unique_ptr<ScopedOverviewAnimationSettings>>;

  // Calculates and returns an optimal scale ratio. This is only taking into
  // account height as the width can vary.
  static float GetItemScale(int source_height,
                            int target_height,
                            int top_view_inset,
                            int title_height);

  ScopedOverviewTransformWindow(OverviewItem* overview_item,
                                aura::Window* window);
  ScopedOverviewTransformWindow(const ScopedOverviewTransformWindow&) = delete;
  ScopedOverviewTransformWindow& operator=(
      const ScopedOverviewTransformWindow&) = delete;
  ~ScopedOverviewTransformWindow() override;

  aura::Window* window() const { return window_; }

  bool is_restoring() const { return is_restoring_; }

  OverviewItemFillMode fill_mode() const { return fill_mode_; }

  // 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(
  //      OVERVIEW_ANIMATION_RESTORE_WINDOW, &animation_settings);
  //  // Calls to SetTransform & SetOpacity will use the same animation settings
  //  // until animation_settings is destroyed.
  //  SetTransform(root_window, new_transform) in `overview_utils.h`;
  //  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.
  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
  // `animate` is false, the window will just be restored and not animated. 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, bool animate);

  // Prepares for overview mode by doing any necessary actions before entering.
  void PrepareForOverview();

  // Sets the opacity of the managed windows.
  void SetOpacity(float opacity);

  // Apply clipping on the `window_`. Clip always starts on the origin of
  // `window_`'s layer.
  void SetClipping(const gfx::Rect& clip_rect);

  // 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.
  gfx::RectF ShrinkRectToFitPreservingAspectRatio(const gfx::RectF& rect,
                                                  const gfx::RectF& bounds,
                                                  int top_view_inset,
                                                  int title_height) const;

  // 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();

  // Closes the transient root of the window managed by |this|.
  void Close();

  bool IsMinimizedOrTucked() 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 UpdateOverviewItemFillMode();

  // Updates the rounded corners on `window_` and its transient hierarchy (if
  // needed).
  void UpdateRoundedCorners(bool show);

  // aura::client::TransientWindowClientObserver:
  void OnTransientChildWindowAdded(aura::Window* parent,
                                   aura::Window* transient_child) override;
  void OnTransientChildWindowRemoved(aura::Window* parent,
                                     aura::Window* transient_child) override;

  // aura::WindowObserver:
  void OnWindowPropertyChanged(aura::Window* window,
                               const void* key,
                               intptr_t old) override;
  void OnWindowBoundsChanged(aura::Window* window,
                             const gfx::Rect& old_bounds,
                             const gfx::Rect& new_bounds,
                             ui::PropertyChangeReason reason) override;
  void OnWindowDestroying(aura::Window* window) override;

  // If true, makes `CloseWidget()` execute synchronously when used in tests.
  static void SetImmediateCloseForTests(bool immediate);

 private:
  friend class OverviewTestBase;
  FRIEND_TEST_ALL_PREFIXES(OverviewSessionTest, CloseAnimationShadow);
  class LayerCachingAndFilteringObserver;

  // Closes the window managed by |this|.
  void CloseWidget();

  // Adds transient windows that should be hidden to the hidden window list. The
  // windows are hidden in overview mode and the visibility of the windows is
  // recovered after overview mode.
  void AddHiddenTransientWindows(
      const std::vector<raw_ptr<aura::Window, VectorExperimental>>&
          transient_windows);

  // A weak pointer to the overview item that owns |this|. Guaranteed to be not
  // null for the lifetime of |this|.
  raw_ptr<OverviewItem> overview_item_;

  // A weak pointer to the real window in the overview.
  raw_ptr<aura::Window> window_;

  // True during the process of `RestoreWindow()`. This prevents redundant
  // cyclic calls to `OverviewItem::SetBounds()`, which may happen when
  // `ScopedOverviewTransformWindow::OnWindowBoundsChanged()` is triggered
  // during the restore see http://b/311255082 for an example.
  bool is_restoring_ = false;

  // The original opacity of the window before entering overview mode.
  float original_opacity_;

  // Specifies how the window is laid out in the grid.
  OverviewItemFillMode fill_mode_ = OverviewItemFillMode::kNormal;

  // 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.
  std::vector<std::unique_ptr<LayerCachingAndFilteringObserver>>
      cached_and_filtered_layer_observers_;

  // For the duration of this object |window_| and its transient childrens'
  // event targeting policy will be sent to NONE. Store the originals so we can
  // change it back when destroying |this|.
  base::flat_map<aura::Window*,
                 std::unique_ptr<aura::ScopedWindowEventTargetingBlocker>>
      event_targeting_blocker_map_;

  // The original clipping on the layer of the window before entering overview
  // mode.
  gfx::Rect original_clip_rect_;

  // Removes clipping on `window_` during destruction in the case it was not
  // removed in `RestoreWindw()`. See destructor for more information.
  bool reset_clip_on_shutdown_ = true;

  std::unique_ptr<ScopedOverviewHideWindows> hidden_transient_children_;

  base::ScopedMultiSourceObservation<aura::Window, aura::WindowObserver>
      window_observations_{this};

  std::unique_ptr<ScopedWindowTreeSynchronizer> window_tree_synchronizer_;

  // While the transform window exists, apply dynamic raster scale to the
  // underlying window.
  std::optional<ScopedRasterScaleLayerObserverLock> raster_scale_observer_lock_;

  base::WeakPtrFactory<ScopedOverviewTransformWindow> weak_ptr_factory_{this};
};

}  // namespace ash

#endif  // ASH_WM_OVERVIEW_SCOPED_OVERVIEW_TRANSFORM_WINDOW_H_