drag_window_from_shelf_controller.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_
  5. #define ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_
  6. #include <vector>
  7. #include "ash/ash_export.h"
  8. #include "ash/public/cpp/shelf_types.h"
  9. #include "ash/public/cpp/window_properties.h"
  10. #include "ash/shelf/shelf_metrics.h"
  11. #include "ash/wm/splitview/split_view_controller.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/observer_list.h"
  14. #include "base/timer/timer.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. #include "ui/aura/window_observer.h"
  17. namespace aura {
  18. class Window;
  19. }
  20. namespace gfx {
  21. class PointF;
  22. }
  23. namespace ash {
  24. // The window drag controller that will be used when a window is dragged up by
  25. // swiping up from the shelf to homescreen, overview or splitview.
  26. class ASH_EXPORT DragWindowFromShelfController : public aura::WindowObserver {
  27. public:
  28. // The deceleration threshold to open overview behind the dragged window
  29. // when swiping up from the shelf to drag the active window.
  30. static constexpr float kOpenOverviewThreshold = 10.f;
  31. // The deceleration threshold to show or hide overview during window dragging
  32. // when dragging a window up from the shelf.
  33. static constexpr float kShowOverviewThreshold = 50.f;
  34. // The upward velocity threshold to take the user to the home launcher screen
  35. // when swiping up from the shelf. Can happen anytime during dragging.
  36. static constexpr float kVelocityToHomeScreenThreshold = 1000.f;
  37. // When swiping up from the shelf, the user can continue dragging and end with
  38. // a downward fling. This is the downward velocity threshold required to
  39. // restore the original window bounds.
  40. static constexpr float kVelocityToRestoreBoundsThreshold = 1000.f;
  41. // The upward velocity threshold to fling the window into overview when split
  42. // view is active during dragging.
  43. static constexpr float kVelocityToOverviewThreshold = 1000.f;
  44. // If the window drag starts within |kDistanceFromEdge| from screen edge, it
  45. // will get snapped if the drag ends in the snap region, no matter how far
  46. // the window has been dragged.
  47. static constexpr int kDistanceFromEdge = 8;
  48. // A window has to be dragged toward the direction of the edge of the screen
  49. // for a minimum of |kMinDragDistance| to a point within
  50. // |kScreenEdgeInsetForSnap| of the edge of the screen, or dragged inside
  51. // |kDistanceFromEdge| from edge to be snapped.
  52. static constexpr int kScreenEdgeInsetForSnap = 48;
  53. static constexpr int kMinDragDistance = 96;
  54. // The distance for the dragged window to pass over the bottom of the display
  55. // so that it can be dragged into home launcher or overview. If not pass this
  56. // value (the top of the hotseat), the window will snap back to its original
  57. // position. The value is different for standard or dense shelf.
  58. static float GetReturnToMaximizedThreshold();
  59. class Observer : public base::CheckedObserver {
  60. public:
  61. // Called when overview visibility is changed during or after window
  62. // dragging.
  63. virtual void OnOverviewVisibilityChanged(bool visible) {}
  64. };
  65. DragWindowFromShelfController(aura::Window* window,
  66. const gfx::PointF& location_in_screen);
  67. DragWindowFromShelfController(const DragWindowFromShelfController&) = delete;
  68. DragWindowFromShelfController& operator=(
  69. const DragWindowFromShelfController&) = delete;
  70. ~DragWindowFromShelfController() override;
  71. // Called during swiping up on the shelf.
  72. void Drag(const gfx::PointF& location_in_screen,
  73. float scroll_x,
  74. float scroll_y);
  75. absl::optional<ShelfWindowDragResult> EndDrag(
  76. const gfx::PointF& location_in_screen,
  77. absl::optional<float> velocity_y);
  78. void CancelDrag();
  79. bool IsDraggedWindowAnimating() const;
  80. // Performs the action on the dragged window depending on
  81. // |window_drag_result_|, such as scaling up/down the dragged window. This
  82. // method should be called after EndDrag() which computes
  83. // |window_drag_result_|.
  84. void FinalizeDraggedWindow();
  85. // aura::WindowObserver:
  86. void OnWindowDestroying(aura::Window* window) override;
  87. void AddObserver(Observer* observer);
  88. void RemoveObserver(Observer* observer);
  89. aura::Window* dragged_window() const { return window_; }
  90. bool drag_started() const { return drag_started_; }
  91. bool show_overview_windows() const { return show_overview_windows_; }
  92. bool during_window_restoration_callback() const {
  93. return during_window_restoration_callback_;
  94. }
  95. private:
  96. class WindowsHider;
  97. void OnDragStarted(const gfx::PointF& location_in_screen);
  98. void OnDragEnded(const gfx::PointF& location_in_screen,
  99. bool should_drop_window_in_overview,
  100. SplitViewController::SnapPosition snap_position);
  101. // Updates the dragged window's transform during dragging.
  102. void UpdateDraggedWindow(const gfx::PointF& location_in_screen);
  103. // Returns the desired snap position on |location_in_screen| during dragging.
  104. SplitViewController::SnapPosition GetSnapPosition(
  105. const gfx::PointF& location_in_screen) const;
  106. // Returns true if the dragged window should restore to its original bounds
  107. // after drag ends. Happens when the bottom of the dragged window is
  108. // within the GetReturnToMaximizedThreshold() threshold, or when the downward
  109. // vertical velocity is larger than kVelocityToRestoreBoundsThreshold.
  110. bool ShouldRestoreToOriginalBounds(const gfx::PointF& location_in_screen,
  111. absl::optional<float> velocity_y) const;
  112. // Returns true if we should go to home screen after drag ends. Happens when
  113. // the upward vertical velocity is larger than kVelocityToHomeScreenThreshold
  114. // and splitview is not active. Note when splitview is active, we do not allow
  115. // to go to home screen by fling.
  116. bool ShouldGoToHomeScreen(const gfx::PointF& location_in_screen,
  117. absl::optional<float> velocity_y) const;
  118. // Returns the desired snap position on |location_in_screen| when drag ends.
  119. SplitViewController::SnapPosition GetSnapPositionOnDragEnd(
  120. const gfx::PointF& location_in_screen,
  121. absl::optional<float> velocity_y) const;
  122. // Returns true if we should drop the dragged window in overview after drag
  123. // ends.
  124. bool ShouldDropWindowInOverview(const gfx::PointF& location_in_screen,
  125. absl::optional<float> velocity_y) const;
  126. // Reshows the windows that were hidden before drag starts.
  127. void ReshowHiddenWindowsOnDragEnd();
  128. // Calls when the user resumes or ends window dragging. Overview should show
  129. // up and split view indicators should be updated.
  130. void ShowOverviewDuringOrAfterDrag();
  131. // Overview should be hidden when the user drags the window quickly up or
  132. // around.
  133. void HideOverviewDuringDrag();
  134. // Called when the dragged window should scale down and fade out to home
  135. // screen after drag ends.
  136. void ScaleDownWindowAfterDrag();
  137. // Callback function to be called after the window has been scaled down and
  138. // faded out after drag ends.
  139. void OnWindowScaledDownAfterDrag();
  140. // Called when the dragged window should scale up to restore to its original
  141. // bounds after drag ends.
  142. void ScaleUpToRestoreWindowAfterDrag();
  143. // Callback function to be called after the window has been restored to its
  144. // original bounds after drag ends.
  145. void OnWindowRestoredToOrignalBounds(bool end_overview);
  146. // Called to do proper initialization in overview for the dragged window. The
  147. // function is supposed to be called with an active overview session.
  148. void OnWindowDragStartedInOverview();
  149. aura::Window* window_ = nullptr;
  150. gfx::PointF initial_location_in_screen_;
  151. gfx::PointF previous_location_in_screen_;
  152. bool drag_started_ = false;
  153. // Whether overview was active when the drag started.
  154. bool started_in_overview_ = false;
  155. // Hide all eligible windows during window dragging. Depends on different
  156. // scenarios, we may or may not reshow there windows when drag ends.
  157. std::unique_ptr<WindowsHider> windows_hider_;
  158. // Timer to show and update overview.
  159. base::OneShotTimer show_overview_timer_;
  160. // True if overview is active and its windows are showing.
  161. bool show_overview_windows_ = false;
  162. // A pending action from EndDrag() to be performed in FinalizeDraggedWindow().
  163. absl::optional<ShelfWindowDragResult> window_drag_result_;
  164. base::ObserverList<Observer> observers_;
  165. bool during_window_restoration_callback_ = false;
  166. SplitViewController::SnapPosition initial_snap_position_ =
  167. SplitViewController::NONE;
  168. SplitViewController::SnapPosition end_snap_position_ =
  169. SplitViewController::NONE;
  170. std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
  171. base::WeakPtrFactory<DragWindowFromShelfController> weak_ptr_factory_{this};
  172. };
  173. } // namespace ash
  174. #endif // ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_