123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- // Copyright 2019 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.
- #ifndef ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_
- #define ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_
- #include <vector>
- #include "ash/ash_export.h"
- #include "ash/public/cpp/shelf_types.h"
- #include "ash/public/cpp/window_properties.h"
- #include "ash/shelf/shelf_metrics.h"
- #include "ash/wm/splitview/split_view_controller.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "base/timer/timer.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "ui/aura/window_observer.h"
- namespace aura {
- class Window;
- }
- namespace gfx {
- class PointF;
- }
- namespace ash {
- // The window drag controller that will be used when a window is dragged up by
- // swiping up from the shelf to homescreen, overview or splitview.
- class ASH_EXPORT DragWindowFromShelfController : public aura::WindowObserver {
- public:
- // The deceleration threshold to open overview behind the dragged window
- // when swiping up from the shelf to drag the active window.
- static constexpr float kOpenOverviewThreshold = 10.f;
- // The deceleration threshold to show or hide overview during window dragging
- // when dragging a window up from the shelf.
- static constexpr float kShowOverviewThreshold = 50.f;
- // The upward velocity threshold to take the user to the home launcher screen
- // when swiping up from the shelf. Can happen anytime during dragging.
- static constexpr float kVelocityToHomeScreenThreshold = 1000.f;
- // When swiping up from the shelf, the user can continue dragging and end with
- // a downward fling. This is the downward velocity threshold required to
- // restore the original window bounds.
- static constexpr float kVelocityToRestoreBoundsThreshold = 1000.f;
- // The upward velocity threshold to fling the window into overview when split
- // view is active during dragging.
- static constexpr float kVelocityToOverviewThreshold = 1000.f;
- // If the window drag starts within |kDistanceFromEdge| from screen edge, it
- // will get snapped if the drag ends in the snap region, no matter how far
- // the window has been dragged.
- static constexpr int kDistanceFromEdge = 8;
- // A window has to be dragged toward the direction of the edge of the screen
- // for a minimum of |kMinDragDistance| to a point within
- // |kScreenEdgeInsetForSnap| of the edge of the screen, or dragged inside
- // |kDistanceFromEdge| from edge to be snapped.
- static constexpr int kScreenEdgeInsetForSnap = 48;
- static constexpr int kMinDragDistance = 96;
- // The distance for the dragged window to pass over the bottom of the display
- // so that it can be dragged into home launcher or overview. If not pass this
- // value (the top of the hotseat), the window will snap back to its original
- // position. The value is different for standard or dense shelf.
- static float GetReturnToMaximizedThreshold();
- class Observer : public base::CheckedObserver {
- public:
- // Called when overview visibility is changed during or after window
- // dragging.
- virtual void OnOverviewVisibilityChanged(bool visible) {}
- };
- DragWindowFromShelfController(aura::Window* window,
- const gfx::PointF& location_in_screen);
- DragWindowFromShelfController(const DragWindowFromShelfController&) = delete;
- DragWindowFromShelfController& operator=(
- const DragWindowFromShelfController&) = delete;
- ~DragWindowFromShelfController() override;
- // Called during swiping up on the shelf.
- void Drag(const gfx::PointF& location_in_screen,
- float scroll_x,
- float scroll_y);
- absl::optional<ShelfWindowDragResult> EndDrag(
- const gfx::PointF& location_in_screen,
- absl::optional<float> velocity_y);
- void CancelDrag();
- bool IsDraggedWindowAnimating() const;
- // Performs the action on the dragged window depending on
- // |window_drag_result_|, such as scaling up/down the dragged window. This
- // method should be called after EndDrag() which computes
- // |window_drag_result_|.
- void FinalizeDraggedWindow();
- // aura::WindowObserver:
- void OnWindowDestroying(aura::Window* window) override;
- void AddObserver(Observer* observer);
- void RemoveObserver(Observer* observer);
- aura::Window* dragged_window() const { return window_; }
- bool drag_started() const { return drag_started_; }
- bool show_overview_windows() const { return show_overview_windows_; }
- bool during_window_restoration_callback() const {
- return during_window_restoration_callback_;
- }
- private:
- class WindowsHider;
- void OnDragStarted(const gfx::PointF& location_in_screen);
- void OnDragEnded(const gfx::PointF& location_in_screen,
- bool should_drop_window_in_overview,
- SplitViewController::SnapPosition snap_position);
- // Updates the dragged window's transform during dragging.
- void UpdateDraggedWindow(const gfx::PointF& location_in_screen);
- // Returns the desired snap position on |location_in_screen| during dragging.
- SplitViewController::SnapPosition GetSnapPosition(
- const gfx::PointF& location_in_screen) const;
- // Returns true if the dragged window should restore to its original bounds
- // after drag ends. Happens when the bottom of the dragged window is
- // within the GetReturnToMaximizedThreshold() threshold, or when the downward
- // vertical velocity is larger than kVelocityToRestoreBoundsThreshold.
- bool ShouldRestoreToOriginalBounds(const gfx::PointF& location_in_screen,
- absl::optional<float> velocity_y) const;
- // Returns true if we should go to home screen after drag ends. Happens when
- // the upward vertical velocity is larger than kVelocityToHomeScreenThreshold
- // and splitview is not active. Note when splitview is active, we do not allow
- // to go to home screen by fling.
- bool ShouldGoToHomeScreen(const gfx::PointF& location_in_screen,
- absl::optional<float> velocity_y) const;
- // Returns the desired snap position on |location_in_screen| when drag ends.
- SplitViewController::SnapPosition GetSnapPositionOnDragEnd(
- const gfx::PointF& location_in_screen,
- absl::optional<float> velocity_y) const;
- // Returns true if we should drop the dragged window in overview after drag
- // ends.
- bool ShouldDropWindowInOverview(const gfx::PointF& location_in_screen,
- absl::optional<float> velocity_y) const;
- // Reshows the windows that were hidden before drag starts.
- void ReshowHiddenWindowsOnDragEnd();
- // Calls when the user resumes or ends window dragging. Overview should show
- // up and split view indicators should be updated.
- void ShowOverviewDuringOrAfterDrag();
- // Overview should be hidden when the user drags the window quickly up or
- // around.
- void HideOverviewDuringDrag();
- // Called when the dragged window should scale down and fade out to home
- // screen after drag ends.
- void ScaleDownWindowAfterDrag();
- // Callback function to be called after the window has been scaled down and
- // faded out after drag ends.
- void OnWindowScaledDownAfterDrag();
- // Called when the dragged window should scale up to restore to its original
- // bounds after drag ends.
- void ScaleUpToRestoreWindowAfterDrag();
- // Callback function to be called after the window has been restored to its
- // original bounds after drag ends.
- void OnWindowRestoredToOrignalBounds(bool end_overview);
- // Called to do proper initialization in overview for the dragged window. The
- // function is supposed to be called with an active overview session.
- void OnWindowDragStartedInOverview();
- aura::Window* window_ = nullptr;
- gfx::PointF initial_location_in_screen_;
- gfx::PointF previous_location_in_screen_;
- bool drag_started_ = false;
- // Whether overview was active when the drag started.
- bool started_in_overview_ = false;
- // Hide all eligible windows during window dragging. Depends on different
- // scenarios, we may or may not reshow there windows when drag ends.
- std::unique_ptr<WindowsHider> windows_hider_;
- // Timer to show and update overview.
- base::OneShotTimer show_overview_timer_;
- // True if overview is active and its windows are showing.
- bool show_overview_windows_ = false;
- // A pending action from EndDrag() to be performed in FinalizeDraggedWindow().
- absl::optional<ShelfWindowDragResult> window_drag_result_;
- base::ObserverList<Observer> observers_;
- bool during_window_restoration_callback_ = false;
- SplitViewController::SnapPosition initial_snap_position_ =
- SplitViewController::NONE;
- SplitViewController::SnapPosition end_snap_position_ =
- SplitViewController::NONE;
- std::unique_ptr<ui::PresentationTimeRecorder> presentation_time_recorder_;
- base::WeakPtrFactory<DragWindowFromShelfController> weak_ptr_factory_{this};
- };
- } // namespace ash
- #endif // ASH_SHELF_DRAG_WINDOW_FROM_SHELF_CONTROLLER_H_
|