blob: 813dd1da9970354937accebef39a992d0e7f709b [file] [log] [blame]
[email protected]bb612db2012-01-09 17:31:131// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]084b6bb2011-11-17 05:18:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]2f744282011-12-23 22:40:525#ifndef ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_
6#define ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_
[email protected]084b6bb2011-11-17 05:18:167
dchenga94547472016-04-08 08:41:118#include <memory>
9
[email protected]b65bdda2011-12-23 23:35:3110#include "ash/ash_export.h"
Scott Violet9838c932017-06-19 20:54:5111#include "ash/display/window_tree_host_manager.h"
Jonah55ab85e82021-12-07 17:57:4012#include "ash/drag_drop/drag_drop_capture_delegate.h"
Collin Bakerc6fae372020-05-01 23:37:4713#include "ash/drag_drop/tab_drag_drop_delegate.h"
[email protected]8e937c1e2012-06-28 22:57:3014#include "base/callback.h"
[email protected]ffa4e4482012-11-28 12:11:4915#include "base/memory/weak_ptr.h"
Daichi Hironoe66b4152017-08-01 06:20:3316#include "base/observer_list.h"
Evan Stade55a443f2017-07-20 19:41:0217#include "base/time/time.h"
Anton Bikineev43cee28e2021-05-14 23:35:3318#include "third_party/abseil-cpp/absl/types/optional.h"
sky92d41b242016-10-27 20:10:1619#include "ui/aura/client/drag_drop_client.h"
Aya ElAttar2e554e52021-01-11 13:03:4320#include "ui/aura/client/drag_drop_delegate.h"
[email protected]341ad582012-02-03 18:31:0921#include "ui/aura/window_observer.h"
Henrique Ferreiro1748fd12020-08-04 12:51:4622#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
[email protected]084b6bb2011-11-17 05:18:1623#include "ui/base/dragdrop/os_exchange_data.h"
[email protected]86ccbd42013-09-18 18:11:5424#include "ui/events/event_constants.h"
25#include "ui/events/event_handler.h"
[email protected]ffb15d12013-09-15 17:29:3026#include "ui/gfx/animation/animation_delegate.h"
Avi Drissmanfefc2f82014-12-22 19:25:2927#include "ui/gfx/geometry/rect.h"
Allen Bauer35d4e722020-06-16 22:47:5628#include "ui/views/widget/unique_widget_ptr.h"
[email protected]084b6bb2011-11-17 05:18:1629
[email protected]ffb15d12013-09-15 17:29:3030namespace gfx {
[email protected]96fe25bf2012-11-27 20:30:2531class LinearAnimation;
[email protected]bb612db2012-01-09 17:31:1332}
33
sky4f4d2592016-10-28 17:14:4734namespace ui {
35class LocatedEvent;
36}
37
[email protected]55f593352011-12-24 05:42:4638namespace ash {
Nick Diego Yamanef258eb442020-10-28 04:57:1639class ToplevelWindowDragDelegate;
[email protected]084b6bb2011-11-17 05:18:1640
jamescookb8dcef522016-06-25 14:42:5541class ASH_EXPORT DragDropController : public aura::client::DragDropClient,
42 public ui::EventHandler,
43 public gfx::AnimationDelegate,
jamescook035dc062016-08-05 21:13:5244 public aura::WindowObserver,
Scott Violet9838c932017-06-19 20:54:5145 public WindowTreeHostManager::Observer {
[email protected]828a6dfa2012-05-10 20:03:0246 public:
[email protected]084b6bb2011-11-17 05:18:1647 DragDropController();
Peter Boströmec31a042021-09-16 23:37:3448
49 DragDropController(const DragDropController&) = delete;
50 DragDropController& operator=(const DragDropController&) = delete;
51
dcheng34dfcbe2014-10-29 18:58:1952 ~DragDropController() override;
[email protected]084b6bb2011-11-17 05:18:1653
James Cookeb426b52018-09-17 16:45:1254 void set_enabled(bool enabled) { enabled_ = enabled; }
55
Nick Diego Yamanef258eb442020-10-28 04:57:1656 void set_toplevel_window_drag_delegate(ToplevelWindowDragDelegate* delegate) {
57 toplevel_window_drag_delegate_ = delegate;
58 }
59
[email protected]458b365c2011-12-15 05:04:0960 // Overridden from aura::client::DragDropClient:
Henrique Ferreirod7b970da2021-04-16 19:36:4461 ui::mojom::DragOperation StartDragAndDrop(
62 std::unique_ptr<ui::OSExchangeData> data,
63 aura::Window* root_window,
64 aura::Window* source_window,
65 const gfx::Point& screen_location,
66 int allowed_operations,
67 ui::mojom::DragEventSource source) override;
dcheng34dfcbe2014-10-29 18:58:1968 void DragCancel() override;
69 bool IsDragDropInProgress() override;
Daichi Hironoe66b4152017-08-01 06:20:3370 void AddObserver(aura::client::DragDropClientObserver* observer) override;
71 void RemoveObserver(aura::client::DragDropClientObserver* observer) override;
[email protected]084b6bb2011-11-17 05:18:1672
[email protected]304594c2012-11-13 16:35:2773 // Overridden from ui::EventHandler:
dcheng34dfcbe2014-10-29 18:58:1974 void OnKeyEvent(ui::KeyEvent* event) override;
75 void OnMouseEvent(ui::MouseEvent* event) override;
76 void OnTouchEvent(ui::TouchEvent* event) override;
77 void OnGestureEvent(ui::GestureEvent* event) override;
[email protected]084b6bb2011-11-17 05:18:1678
[email protected]341ad582012-02-03 18:31:0979 // Overridden from aura::WindowObserver.
Mitsuru Oshimaf47a9382022-01-20 20:34:2180 void OnWindowDestroying(aura::Window* window) override;
[email protected]341ad582012-02-03 18:31:0981
Fergus Dalla4293852019-07-26 07:13:4782 void SetDragImage(const gfx::ImageSkia& image,
83 const gfx::Vector2d& image_offset);
84
Mitsuru Oshima0a710102022-01-11 21:15:5685 // Sets the `closure` that will be executed as a replacement of
86 // inner event loop. A test can use this closure to generate events, or
87 // take other actions that should happen during the drag and drop, and
88 // can also check the condition that should be satisfied.
89 // The loop closure is called with a boolean value that indicates
90 // that this is called from the inner loop because the same closure will
91 // often used to generate the event that will eventually enter the drag
92 // and drop inner loop. The `quit_closure` is used for a test
93 // to exit the outer loop in the test.
94 using TestLoopClosure = base::RepeatingCallback<void()>;
95 void SetLoopClosureForTesting(TestLoopClosure closure,
96 base::OnceClosure quit_closure);
97
98 void SetDisableNestedLoopForTesting(bool disable);
99
100 // Deprecated: Use `SetDisableNestedLoopForTesting`.
101 void set_should_block_during_drag_drop(bool should_block_during_drag_drop) {
102 SetDisableNestedLoopForTesting(!should_block_during_drag_drop);
103 }
104
[email protected]ffa4e4482012-11-28 12:11:49105 protected:
[email protected]c08610452012-11-28 21:48:36106 // Helper method to create a LinearAnimation object that will run the drag
107 // cancel animation. Caller take ownership of the returned object. Protected
108 // for testing.
[email protected]ffb15d12013-09-15 17:29:30109 virtual gfx::LinearAnimation* CreateCancelAnimation(
Evan Stade55a443f2017-07-20 19:41:02110 base::TimeDelta duration,
[email protected]c08610452012-11-28 21:48:36111 int frame_rate,
[email protected]ffb15d12013-09-15 17:29:30112 gfx::AnimationDelegate* delegate);
[email protected]c08610452012-11-28 21:48:36113
sky4f4d2592016-10-28 17:14:47114 // Exposed for tests to override.
115 virtual void DragUpdate(aura::Window* target, const ui::LocatedEvent& event);
116 virtual void Drop(aura::Window* target, const ui::LocatedEvent& event);
117
[email protected]ffa4e4482012-11-28 12:11:49118 // Actual implementation of |DragCancel()|. protected for testing.
Evan Stade55a443f2017-07-20 19:41:02119 virtual void DoDragCancel(base::TimeDelta drag_cancel_animation_duration);
[email protected]ffa4e4482012-11-28 12:11:49120
Jonah55ab85e82021-12-07 17:57:40121 // Exposed for test assertions.
122 DragDropCaptureDelegate* get_capture_delegate() { return capture_delegate_; }
123
[email protected]084b6bb2011-11-17 05:18:16124 private:
James Cook317781a2017-07-18 02:08:06125 friend class DragDropControllerTest;
James Cookeb426b52018-09-17 16:45:12126 friend class DragDropControllerTestApi;
[email protected]084b6bb2011-11-17 05:18:16127
[email protected]ffb15d12013-09-15 17:29:30128 // Overridden from gfx::AnimationDelegate:
dcheng34dfcbe2014-10-29 18:58:19129 void AnimationEnded(const gfx::Animation* animation) override;
130 void AnimationProgressed(const gfx::Animation* animation) override;
131 void AnimationCanceled(const gfx::Animation* animation) override;
[email protected]bb612db2012-01-09 17:31:13132
Scott Violet9838c932017-06-19 20:54:51133 // WindowTreeHostManager::Observer:
jamescook035dc062016-08-05 21:13:52134 void OnDisplayConfigurationChanging() override;
135
[email protected]bb612db2012-01-09 17:31:13136 // Helper method to start drag widget flying back animation.
Evan Stade55a443f2017-07-20 19:41:02137 void StartCanceledAnimation(base::TimeDelta animation_duration);
[email protected]ffa4e4482012-11-28 12:11:49138
139 // Helper method to forward |pending_log_tap_| event to |drag_source_window_|.
140 void ForwardPendingLongTap();
[email protected]bb612db2012-01-09 17:31:13141
[email protected]084b6bb2011-11-17 05:18:16142 // Helper method to reset everything.
143 void Cleanup();
144
Aya ElAttarfd5ce86f2021-09-23 18:20:00145 // Helper method to perform the drop if allowed by
146 // DataTransferPolicyController. If it's run, `drag_cancel` will be replaced.
147 // Otherwise `drag_cancel` will run to cancel the drag.
148 void PerformDrop(const gfx::Point drop_location_in_screen,
149 ui::DropTargetEvent event,
150 std::unique_ptr<ui::OSExchangeData> drag_data,
151 aura::client::DragDropDelegate::DropCallback drop_cb,
152 std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate,
153 base::ScopedClosureRunner drag_cancel);
154
Jonah4b609892021-11-09 22:51:07155 void CancelIfInProgress();
156
James Cookeb426b52018-09-17 16:45:12157 bool enabled_ = false;
Allen Bauer35d4e722020-06-16 22:47:56158 views::UniqueWidgetPtr drag_image_widget_;
[email protected]ceb36f7d2012-10-31 18:33:24159 gfx::Vector2d drag_image_offset_;
Navid Zolghadr0beb8292019-07-08 18:54:04160 std::unique_ptr<ui::OSExchangeData> drag_data_;
Henrique Ferreirod7b970da2021-04-16 19:36:44161 int allowed_operations_ = 0;
162 ui::mojom::DragOperation operation_ = ui::mojom::DragOperation::kNone;
Aya ElAttar2e554e52021-01-11 13:03:43163 aura::client::DragUpdateInfo current_drag_info_;
[email protected]6a5fc422012-03-06 04:43:26164
Collin Bakerc6fae372020-05-01 23:37:47165 // Used when processing a Chrome tab drag from a WebUI tab strip.
Aya ElAttarfd5ce86f2021-09-23 18:20:00166 std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate_;
Collin Baker7f9a1652020-04-28 20:18:16167
[email protected]6a5fc422012-03-06 04:43:26168 // Window that is currently under the drag cursor.
Allen Bauer35d4e722020-06-16 22:47:56169 aura::Window* drag_window_ = nullptr;
[email protected]ffa4e4482012-11-28 12:11:49170
171 // Starting and final bounds for the drag image for the drag cancel animation.
172 gfx::Rect drag_image_initial_bounds_for_cancel_animation_;
173 gfx::Rect drag_image_final_bounds_for_cancel_animation_;
[email protected]96fe25bf2012-11-27 20:30:25174
dchenga94547472016-04-08 08:41:11175 std::unique_ptr<gfx::LinearAnimation> cancel_animation_;
sangwoo843c6cda2019-12-06 00:15:51176 std::unique_ptr<gfx::AnimationDelegate> cancel_animation_notifier_;
[email protected]084b6bb2011-11-17 05:18:16177
[email protected]ffa4e4482012-11-28 12:11:49178 // Window that started the drag.
Allen Bauer35d4e722020-06-16 22:47:56179 aura::Window* drag_source_window_ = nullptr;
[email protected]ffa4e4482012-11-28 12:11:49180
Mitsuru Oshima0a710102022-01-11 21:15:56181 // A closure that allows a test to implement the actions within
182 // drag and drop event loop.
183 TestLoopClosure test_loop_closure_;
184
185 // True if the nested event loop is disabled.
186 bool nested_loop_disabled_for_testing_ = false;
[email protected]084b6bb2011-11-17 05:18:16187
gab2998ee72017-05-05 16:23:50188 // Closure for quitting nested run loop.
Reilly Grantb6702232019-11-26 22:46:04189 base::OnceClosure quit_closure_;
[email protected]8e937c1e2012-06-28 22:57:30190
Jonah55ab85e82021-12-07 17:57:40191 // If non-null, a drag is active which required a capture window.
192 DragDropCaptureDelegate* capture_delegate_;
Jun Mukai14fc3002021-06-22 17:45:38193
Henrique Ferreiro1748fd12020-08-04 12:51:46194 ui::mojom::DragEventSource current_drag_event_source_ =
195 ui::mojom::DragEventSource::kMouse;
[email protected]ffa4e4482012-11-28 12:11:49196
197 // Holds a synthetic long tap event to be sent to the |drag_source_window_|.
198 // See comment in OnGestureEvent() on why we need this.
Jonah4b609892021-11-09 22:51:07199 std::unique_ptr<ui::Event> pending_long_tap_;
[email protected]ffa4e4482012-11-28 12:11:49200
Fergus Dalla4293852019-07-26 07:13:47201 gfx::Point start_location_;
202 gfx::Point current_location_;
203
Trent Apteda250ec3ab2018-08-19 08:52:19204 base::ObserverList<aura::client::DragDropClientObserver>::Unchecked
205 observers_;
Daichi Hironoe66b4152017-08-01 06:20:33206
Nick Diego Yamanef258eb442020-10-28 04:57:16207 ToplevelWindowDragDelegate* toplevel_window_drag_delegate_ = nullptr;
208
Aya ElAttarfd5ce86f2021-09-23 18:20:00209 // Weak ptr for async drop callbacks to be invalidated if a new drag starts.
210 base::WeakPtrFactory<DragDropController> drop_weak_factory_{this};
211
Jeremy Roman47d432e2019-08-20 14:24:00212 base::WeakPtrFactory<DragDropController> weak_factory_{this};
[email protected]084b6bb2011-11-17 05:18:16213};
214
[email protected]55f593352011-12-24 05:42:46215} // namespace ash
[email protected]084b6bb2011-11-17 05:18:16216
[email protected]2f744282011-12-23 22:40:52217#endif // ASH_DRAG_DROP_DRAG_DROP_CONTROLLER_H_