drag_drop_controller.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. // Copyright (c) 2012 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_DRAG_DROP_DRAG_DROP_CONTROLLER_H_
  5. #define ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_
  6. #include <memory>
  7. #include "ash/ash_export.h"
  8. #include "ash/display/window_tree_host_manager.h"
  9. #include "ash/drag_drop/drag_drop_capture_delegate.h"
  10. #include "ash/drag_drop/tab_drag_drop_delegate.h"
  11. #include "base/callback.h"
  12. #include "base/memory/weak_ptr.h"
  13. #include "base/observer_list.h"
  14. #include "base/time/time.h"
  15. #include "third_party/abseil-cpp/absl/types/optional.h"
  16. #include "ui/aura/client/drag_drop_client.h"
  17. #include "ui/aura/client/drag_drop_delegate.h"
  18. #include "ui/aura/window_observer.h"
  19. #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
  20. #include "ui/base/dragdrop/os_exchange_data.h"
  21. #include "ui/events/event_constants.h"
  22. #include "ui/events/event_handler.h"
  23. #include "ui/gfx/animation/animation_delegate.h"
  24. #include "ui/gfx/geometry/rect.h"
  25. #include "ui/views/widget/unique_widget_ptr.h"
  26. namespace gfx {
  27. class LinearAnimation;
  28. }
  29. namespace ui {
  30. class LocatedEvent;
  31. }
  32. namespace ash {
  33. class ToplevelWindowDragDelegate;
  34. class ASH_EXPORT DragDropController : public aura::client::DragDropClient,
  35. public ui::EventHandler,
  36. public gfx::AnimationDelegate,
  37. public aura::WindowObserver,
  38. public WindowTreeHostManager::Observer {
  39. public:
  40. DragDropController();
  41. DragDropController(const DragDropController&) = delete;
  42. DragDropController& operator=(const DragDropController&) = delete;
  43. ~DragDropController() override;
  44. void set_enabled(bool enabled) { enabled_ = enabled; }
  45. void set_toplevel_window_drag_delegate(ToplevelWindowDragDelegate* delegate) {
  46. toplevel_window_drag_delegate_ = delegate;
  47. }
  48. // Overridden from aura::client::DragDropClient:
  49. ui::mojom::DragOperation StartDragAndDrop(
  50. std::unique_ptr<ui::OSExchangeData> data,
  51. aura::Window* root_window,
  52. aura::Window* source_window,
  53. const gfx::Point& screen_location,
  54. int allowed_operations,
  55. ui::mojom::DragEventSource source) override;
  56. void DragCancel() override;
  57. bool IsDragDropInProgress() override;
  58. void AddObserver(aura::client::DragDropClientObserver* observer) override;
  59. void RemoveObserver(aura::client::DragDropClientObserver* observer) override;
  60. // Overridden from ui::EventHandler:
  61. void OnKeyEvent(ui::KeyEvent* event) override;
  62. void OnMouseEvent(ui::MouseEvent* event) override;
  63. void OnTouchEvent(ui::TouchEvent* event) override;
  64. void OnGestureEvent(ui::GestureEvent* event) override;
  65. // Overridden from aura::WindowObserver.
  66. void OnWindowDestroying(aura::Window* window) override;
  67. void SetDragImage(const gfx::ImageSkia& image,
  68. const gfx::Vector2d& image_offset);
  69. ui::mojom::DragEventSource event_source() {
  70. return current_drag_event_source_;
  71. }
  72. // Sets the `closure` that will be executed as a replacement of
  73. // inner event loop. A test can use this closure to generate events, or
  74. // take other actions that should happen during the drag and drop, and
  75. // can also check the condition that should be satisfied.
  76. // The loop closure is called with a boolean value that indicates
  77. // that this is called from the inner loop because the same closure will
  78. // often used to generate the event that will eventually enter the drag
  79. // and drop inner loop. The `quit_closure` is used for a test
  80. // to exit the outer loop in the test.
  81. using TestLoopClosure = base::RepeatingCallback<void()>;
  82. void SetLoopClosureForTesting(TestLoopClosure closure,
  83. base::OnceClosure quit_closure);
  84. void SetDisableNestedLoopForTesting(bool disable);
  85. // Deprecated: Use `SetDisableNestedLoopForTesting`.
  86. void set_should_block_during_drag_drop(bool should_block_during_drag_drop) {
  87. SetDisableNestedLoopForTesting(!should_block_during_drag_drop);
  88. }
  89. protected:
  90. // Helper method to create a LinearAnimation object that will run the drag
  91. // cancel animation. Caller take ownership of the returned object. Protected
  92. // for testing.
  93. virtual gfx::LinearAnimation* CreateCancelAnimation(
  94. base::TimeDelta duration,
  95. int frame_rate,
  96. gfx::AnimationDelegate* delegate);
  97. // Exposed for tests to override.
  98. virtual void DragUpdate(aura::Window* target, const ui::LocatedEvent& event);
  99. virtual void Drop(aura::Window* target, const ui::LocatedEvent& event);
  100. // Actual implementation of |DragCancel()|. protected for testing.
  101. virtual void DoDragCancel(base::TimeDelta drag_cancel_animation_duration);
  102. // Exposed for test assertions.
  103. DragDropCaptureDelegate* get_capture_delegate() { return capture_delegate_; }
  104. private:
  105. friend class DragDropControllerTest;
  106. friend class DragDropControllerTestApi;
  107. // Overridden from gfx::AnimationDelegate:
  108. void AnimationEnded(const gfx::Animation* animation) override;
  109. void AnimationProgressed(const gfx::Animation* animation) override;
  110. void AnimationCanceled(const gfx::Animation* animation) override;
  111. // WindowTreeHostManager::Observer:
  112. void OnDisplayConfigurationChanging() override;
  113. // Helper method to start drag widget flying back animation.
  114. void StartCanceledAnimation(base::TimeDelta animation_duration);
  115. // Helper methods to forward |pending_log_tap_| event to
  116. // |drag_source_window_|.
  117. void ScheduleForwardPendingLongTap();
  118. void ForwardPendingLongTap();
  119. // Helper method to reset most of the state, except state that could be used
  120. // during async operations of cancellation (including cancel animation and
  121. // posting task to dispatch long tap event).
  122. void Cleanup();
  123. void CleanupPendingLongTap();
  124. // Helper method to perform the drop if allowed by
  125. // DataTransferPolicyController. If it's run, `drag_cancel` will be replaced.
  126. // Otherwise `drag_cancel` will run to cancel the drag.
  127. void PerformDrop(const gfx::Point drop_location_in_screen,
  128. ui::DropTargetEvent event,
  129. std::unique_ptr<ui::OSExchangeData> drag_data,
  130. aura::client::DragDropDelegate::DropCallback drop_cb,
  131. std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate,
  132. base::ScopedClosureRunner drag_cancel);
  133. void CancelIfInProgress();
  134. bool enabled_ = false;
  135. views::UniqueWidgetPtr drag_image_widget_;
  136. gfx::Vector2d drag_image_offset_;
  137. std::unique_ptr<ui::OSExchangeData> drag_data_;
  138. int allowed_operations_ = 0;
  139. ui::mojom::DragOperation operation_ = ui::mojom::DragOperation::kNone;
  140. aura::client::DragUpdateInfo current_drag_info_;
  141. // Used when processing a Chrome tab drag from a WebUI tab strip.
  142. std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate_;
  143. // Used when processing a normal drag and drop with touch.
  144. std::unique_ptr<DragDropCaptureDelegate> touch_drag_drop_delegate_;
  145. // Window that is currently under the drag cursor.
  146. aura::Window* drag_window_ = nullptr;
  147. // Starting and final bounds for the drag image for the drag cancel animation.
  148. gfx::Rect drag_image_initial_bounds_for_cancel_animation_;
  149. gfx::Rect drag_image_final_bounds_for_cancel_animation_;
  150. std::unique_ptr<gfx::LinearAnimation> cancel_animation_;
  151. std::unique_ptr<gfx::AnimationDelegate> cancel_animation_notifier_;
  152. // Window that started the drag.
  153. aura::Window* drag_source_window_ = nullptr;
  154. // A closure that allows a test to implement the actions within
  155. // drag and drop event loop.
  156. TestLoopClosure test_loop_closure_;
  157. // True if the nested event loop is disabled.
  158. bool nested_loop_disabled_for_testing_ = false;
  159. // Closure for quitting nested run loop.
  160. base::OnceClosure quit_closure_;
  161. // If non-null, a drag is active which required a capture window.
  162. DragDropCaptureDelegate* capture_delegate_ = nullptr;
  163. ui::mojom::DragEventSource current_drag_event_source_ =
  164. ui::mojom::DragEventSource::kMouse;
  165. // Holds a synthetic long tap event to be sent to the |drag_source_window_|.
  166. // See comment in OnGestureEvent() on why we need this.
  167. std::unique_ptr<ui::Event> pending_long_tap_;
  168. // Set to true during async operations of cancellation (including cancel
  169. // animation and posting task to dispatch long tap event), indicating that a
  170. // long tap event will be dispatched.
  171. bool will_forward_long_tap_ = false;
  172. gfx::Point start_location_;
  173. gfx::Point current_location_;
  174. base::ObserverList<aura::client::DragDropClientObserver>::Unchecked
  175. observers_;
  176. ToplevelWindowDragDelegate* toplevel_window_drag_delegate_ = nullptr;
  177. // Weak ptr for async callbacks to be invalidated if a new drag starts.
  178. base::WeakPtrFactory<DragDropController> weak_factory_{this};
  179. };
  180. } // namespace ash
  181. #endif // ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_