Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: ui/aura/mus/drag_drop_controller_mus.cc

Issue 2455963006: Wires up drag/drop for aura-mus (Closed)
Patch Set: twweaks Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/aura/mus/drag_drop_controller_mus.h ('k') | ui/aura/mus/window_tree_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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
5 #include "ui/aura/mus/drag_drop_controller_mus.h"
6
7 #include <map>
8 #include <string>
9 #include <vector>
10
11 #include "base/auto_reset.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "services/ui/public/interfaces/window_tree.mojom.h"
15 #include "services/ui/public/interfaces/window_tree_constants.mojom.h"
16 #include "ui/aura/client/drag_drop_delegate.h"
17 #include "ui/aura/mus/drag_drop_controller_host.h"
18 #include "ui/aura/mus/mus_types.h"
19 #include "ui/aura/mus/os_exchange_data_provider_mus.h"
20 #include "ui/aura/mus/window_mus.h"
21 #include "ui/aura/window.h"
22 #include "ui/aura/window_tree_host.h"
23 #include "ui/base/dragdrop/drop_target_event.h"
24
25 // Interaction with DragDropDelegate assumes constants are the same.
26 static_assert(ui::DragDropTypes::DRAG_NONE == ui::mojom::kDropEffectNone,
27 "Drag constants must be the same");
28 static_assert(ui::DragDropTypes::DRAG_MOVE == ui::mojom::kDropEffectMove,
29 "Drag constants must be the same");
30 static_assert(ui::DragDropTypes::DRAG_COPY == ui::mojom::kDropEffectCopy,
31 "Drag constants must be the same");
32 static_assert(ui::DragDropTypes::DRAG_LINK == ui::mojom::kDropEffectLink,
33 "Drag constants must be the same");
34
35 namespace aura {
36
37 // State related to a drag initiated by this client.
38 struct DragDropControllerMus::CurrentDragState {
39 Id window_id;
40
41 // The change id of the drag. Used to identify the drag on the server.
42 uint32_t change_id;
43
44 // The result of the drag. This is set on completion and returned to the
45 // caller.
46 uint32_t completed_action;
47
48 // OSExchangeData supplied to StartDragAndDrop().
49 const ui::OSExchangeData& drag_data;
50
51 // StartDragDrop() runs a nested message loop. This closure is used to quit
52 // the run loop when the drag completes.
53 base::Closure runloop_quit_closure;
54 };
55
56 DragDropControllerMus::DragDropControllerMus(
57 DragDropControllerHost* drag_drop_controller_host,
58 ui::mojom::WindowTree* window_tree)
59 : drag_drop_controller_host_(drag_drop_controller_host),
60 window_tree_(window_tree) {}
61
62 DragDropControllerMus::~DragDropControllerMus() {}
63
64 bool DragDropControllerMus::DoesChangeIdMatchDragChangeId(uint32_t id) const {
65 return current_drag_state_ && current_drag_state_->change_id == id;
66 }
67
68 void DragDropControllerMus::OnDragDropStart(
69 std::map<std::string, std::vector<uint8_t>> data) {
70 os_exchange_data_ = base::MakeUnique<ui::OSExchangeData>(
71 base::MakeUnique<aura::OSExchangeDataProviderMus>(std::move(data)));
72 }
73
74 uint32_t DragDropControllerMus::OnDragEnter(WindowMus* window,
75 uint32_t event_flags,
76 const gfx::Point& screen_location,
77 uint32_t effect_bitmask) {
78 return HandleDragEnterOrOver(window, event_flags, screen_location,
79 effect_bitmask, true);
80 }
81
82 uint32_t DragDropControllerMus::OnDragOver(WindowMus* window,
83 uint32_t event_flags,
84 const gfx::Point& screen_location,
85 uint32_t effect_bitmask) {
86 return HandleDragEnterOrOver(window, event_flags, screen_location,
87 effect_bitmask, false);
88 }
89
90 void DragDropControllerMus::OnDragLeave(WindowMus* window) {
91 if (drop_target_window_tracker_.windows().empty())
92 return;
93 DCHECK(window);
94 Window* current_target = drop_target_window_tracker_.Pop();
95 DCHECK_EQ(window->GetWindow(), current_target);
96 client::GetDragDropDelegate(current_target)->OnDragExited();
97 }
98
99 uint32_t DragDropControllerMus::OnCompleteDrop(
100 WindowMus* window,
101 uint32_t event_flags,
102 const gfx::Point& screen_location,
103 uint32_t effect_bitmask) {
104 if (drop_target_window_tracker_.windows().empty())
105 return ui::mojom::kDropEffectNone;
106
107 DCHECK(window);
108 Window* current_target = drop_target_window_tracker_.Pop();
109 DCHECK_EQ(window->GetWindow(), current_target);
110 std::unique_ptr<ui::DropTargetEvent> event = CreateDropTargetEvent(
111 window->GetWindow(), event_flags, screen_location, effect_bitmask);
112 return client::GetDragDropDelegate(current_target)->OnPerformDrop(*event);
113 }
114
115 void DragDropControllerMus::OnPerformDragDropCompleted(uint32_t action_taken) {
116 DCHECK(current_drag_state_);
117 current_drag_state_->completed_action = action_taken;
118 current_drag_state_->runloop_quit_closure.Run();
119 }
120
121 void DragDropControllerMus::OnDragDropDone() {
122 os_exchange_data_.reset();
123 }
124
125 int DragDropControllerMus::StartDragAndDrop(
126 const ui::OSExchangeData& data,
127 Window* root_window,
128 Window* source_window,
129 const gfx::Point& screen_location,
130 int drag_operations,
131 ui::DragDropTypes::DragEventSource source) {
132 DCHECK(!current_drag_state_);
133
134 // TODO(erg): Pass |cursor_location| and |bitmap| in PerformDragDrop() when
135 // we start showing an image representation of the drag under he cursor.
136
137 base::RunLoop run_loop;
138 WindowMus* source_window_mus = WindowMus::Get(source_window);
139 const uint32_t change_id =
140 drag_drop_controller_host_->CreateChangeIdForDrag(source_window_mus);
141 CurrentDragState current_drag_state = {source_window_mus->server_id(),
142 change_id, ui::mojom::kDropEffectNone,
143 data, run_loop.QuitClosure()};
144 base::AutoReset<CurrentDragState*> resetter(&current_drag_state_,
145 &current_drag_state);
146 std::map<std::string, std::vector<uint8_t>> drag_data =
147 static_cast<const aura::OSExchangeDataProviderMus&>(data.provider())
148 .GetData();
149 window_tree_->PerformDragDrop(
150 change_id, source_window_mus->server_id(),
151 mojo::Map<mojo::String, mojo::Array<uint8_t>>::From(drag_data),
152 drag_operations);
153
154 base::MessageLoop* loop = base::MessageLoop::current();
155 base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
156 run_loop.Run();
157
158 return current_drag_state.completed_action;
159 }
160
161 void DragDropControllerMus::DragCancel() {
162 DCHECK(current_drag_state_);
163 // Server will clean up drag and fail the in-flight change.
164 window_tree_->CancelDragDrop(current_drag_state_->window_id);
165 }
166
167 bool DragDropControllerMus::IsDragDropInProgress() {
168 return current_drag_state_ != nullptr;
169 }
170
171 uint32_t DragDropControllerMus::HandleDragEnterOrOver(
172 WindowMus* window,
173 uint32_t event_flags,
174 const gfx::Point& screen_location,
175 uint32_t effect_bitmask,
176 bool is_enter) {
177 client::DragDropDelegate* drag_drop_delegate =
178 window ? client::GetDragDropDelegate(window->GetWindow()) : nullptr;
179 WindowTreeHost* window_tree_host =
180 window ? window->GetWindow()->GetHost() : nullptr;
181 if ((!is_enter && drop_target_window_tracker_.windows().empty()) ||
182 !drag_drop_delegate || !window_tree_host) {
183 drop_target_window_tracker_.RemoveAll();
184 return ui::mojom::kDropEffectNone;
185 }
186 drop_target_window_tracker_.Add(window->GetWindow());
187
188 std::unique_ptr<ui::DropTargetEvent> event = CreateDropTargetEvent(
189 window->GetWindow(), event_flags, screen_location, effect_bitmask);
190 if (is_enter)
191 drag_drop_delegate->OnDragEntered(*event);
192 return drag_drop_delegate->OnDragUpdated(*event);
193 }
194
195 std::unique_ptr<ui::DropTargetEvent>
196 DragDropControllerMus::CreateDropTargetEvent(Window* window,
197 uint32_t event_flags,
198 const gfx::Point& screen_location,
199 uint32_t effect_bitmask) {
200 DCHECK(window->GetHost());
201 gfx::Point root_location = screen_location;
202 window->GetHost()->ConvertPointFromNativeScreen(&root_location);
203 gfx::Point location = root_location;
204 Window::ConvertPointToTarget(window->GetRootWindow(), window, &location);
205 std::unique_ptr<ui::DropTargetEvent> event =
206 base::MakeUnique<ui::DropTargetEvent>(
207 current_drag_state_ ? current_drag_state_->drag_data
208 : *(os_exchange_data_.get()),
209 location, root_location, effect_bitmask);
210 event->set_flags(event_flags);
211 return event;
212 }
213
214 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/mus/drag_drop_controller_mus.h ('k') | ui/aura/mus/window_tree_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698