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

Side by Side Diff: services/ui/ws/drag_controller.cc

Issue 2376583003: mus: Keep track of the drag cursor during DnD operations. (Closed)
Patch Set: style Created 4 years, 2 months 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "services/ui/ws/drag_controller.h" 5 #include "services/ui/ws/drag_controller.h"
6 6
7 #include <utility>
8
7 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "services/ui/public/interfaces/cursor.mojom.h"
11 #include "services/ui/ws/drag_cursor_updater.h"
8 #include "services/ui/ws/drag_source.h" 12 #include "services/ui/ws/drag_source.h"
9 #include "services/ui/ws/drag_target_connection.h" 13 #include "services/ui/ws/drag_target_connection.h"
10 #include "services/ui/ws/event_dispatcher.h" 14 #include "services/ui/ws/event_dispatcher.h"
11 #include "services/ui/ws/server_window.h" 15 #include "services/ui/ws/server_window.h"
12 16
13 namespace ui { 17 namespace ui {
14 namespace ws { 18 namespace ws {
15 19
16 struct DragController::Operation { 20 struct DragController::Operation {
17 OperationType type; 21 OperationType type;
18 uint32_t event_flags; 22 uint32_t event_flags;
19 gfx::Point screen_position; 23 gfx::Point screen_position;
20 }; 24 };
21 25
22 struct DragController::WindowState { 26 struct DragController::WindowState {
23 // Set to true once we've observed the ServerWindow* that is the key to this 27 // Set to true once we've observed the ServerWindow* that is the key to this
24 // instance in |window_state_|. 28 // instance in |window_state_|.
25 bool observed; 29 bool observed = false;
26 30
27 // If we're waiting for a response, this is the type of message. TYPE_NONE 31 // If we're waiting for a response, this is the type of message. NONE means
28 // means there's no outstanding 32 // there's no outstanding
29 OperationType waiting_on_reply; 33 OperationType waiting_on_reply = OperationType::NONE;
30 34
31 // The operation that we'll send off if |waiting_on_reply| isn't TYPE_NONE. 35 // The operation that we'll send off if |waiting_on_reply| isn't NONE.
32 Operation queued_operation; 36 Operation queued_operation = {OperationType::NONE, 0, gfx::Point()};
37
38 // The current set of operations that this window accepts. This gets updated
39 // on each return message.
40 DropEffectBitmask bitmask = 0u;
33 }; 41 };
34 42
35 DragController::DragController( 43 DragController::DragController(
44 DragCursorUpdater* cursor_updater,
36 DragSource* source, 45 DragSource* source,
37 ServerWindow* source_window, 46 ServerWindow* source_window,
38 DragTargetConnection* source_connection, 47 DragTargetConnection* source_connection,
39 int32_t drag_pointer, 48 int32_t drag_pointer,
40 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, 49 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data,
41 uint32_t drag_operations) 50 DropEffectBitmask drag_operations)
42 : source_(source), 51 : source_(source),
52 cursor_updater_(cursor_updater),
43 drag_operations_(drag_operations), 53 drag_operations_(drag_operations),
44 drag_pointer_id_(drag_pointer), 54 drag_pointer_id_(drag_pointer),
55 current_cursor_(static_cast<int32_t>(ui::mojom::Cursor::NO_DROP)),
45 source_window_(source_window), 56 source_window_(source_window),
46 source_connection_(source_connection), 57 source_connection_(source_connection),
47 mime_data_(std::move(mime_data)), 58 mime_data_(std::move(mime_data)),
48 weak_factory_(this) { 59 weak_factory_(this) {
60 SetCurrentTargetWindow(nullptr);
49 EnsureWindowObserved(source_window_); 61 EnsureWindowObserved(source_window_);
50 } 62 }
51 63
52 DragController::~DragController() { 64 DragController::~DragController() {
53 for (auto& pair : window_state_) { 65 for (auto& pair : window_state_) {
54 if (pair.second.observed) 66 if (pair.second.observed)
55 pair.first->RemoveObserver(this); 67 pair.first->RemoveObserver(this);
56 } 68 }
57 } 69 }
58 70
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 134 }
123 135
124 return true; 136 return true;
125 } 137 }
126 138
127 void DragController::OnWillDestroyDragTargetConnection( 139 void DragController::OnWillDestroyDragTargetConnection(
128 DragTargetConnection* connection) { 140 DragTargetConnection* connection) {
129 called_on_drag_mime_types_.erase(connection); 141 called_on_drag_mime_types_.erase(connection);
130 } 142 }
131 143
132 void DragController::MessageDragCompleted(bool success, uint32_t action_taken) { 144 void DragController::MessageDragCompleted(bool success,
145 DropEffect action_taken) {
133 for (DragTargetConnection* connection : called_on_drag_mime_types_) 146 for (DragTargetConnection* connection : called_on_drag_mime_types_)
134 connection->PerformOnDragDropDone(); 147 connection->PerformOnDragDropDone();
135 called_on_drag_mime_types_.clear(); 148 called_on_drag_mime_types_.clear();
136 149
137 source_->OnDragCompleted(success, action_taken); 150 source_->OnDragCompleted(success, action_taken);
138 // |this| may be deleted now. 151 // |this| may be deleted now.
139 } 152 }
140 153
141 size_t DragController::GetSizeOfQueueForWindow(ServerWindow* window) { 154 size_t DragController::GetSizeOfQueueForWindow(ServerWindow* window) {
142 auto it = window_state_.find(window); 155 auto it = window_state_.find(window);
143 if (it == window_state_.end()) 156 if (it == window_state_.end())
144 return 0u; 157 return 0u;
145 if (it->second.waiting_on_reply == OperationType::NONE) 158 if (it->second.waiting_on_reply == OperationType::NONE)
146 return 0u; 159 return 0u;
147 if (it->second.queued_operation.type == OperationType::NONE) 160 if (it->second.queued_operation.type == OperationType::NONE)
148 return 1u; 161 return 1u;
149 return 2u; 162 return 2u;
150 } 163 }
151 164
165 void DragController::SetWindowDropOperations(ServerWindow* window,
166 DropEffectBitmask bitmask) {
167 WindowState& state = window_state_[window];
168 state.bitmask = bitmask;
169
170 if (current_target_window_ == window) {
171 current_cursor_ = CursorForEffectBitmask(bitmask);
172 cursor_updater_->OnDragCursorUpdated();
173 }
174 }
175
176 int32_t DragController::CursorForEffectBitmask(DropEffectBitmask bitmask) {
177 DropEffectBitmask combined = bitmask & drag_operations_;
178 return combined == ui::mojom::kDropEffectNone
179 ? static_cast<int32_t>(ui::mojom::Cursor::NO_DROP)
180 : static_cast<int32_t>(ui::mojom::Cursor::COPY);
181 }
182
152 void DragController::SetCurrentTargetWindow(ServerWindow* current_target) { 183 void DragController::SetCurrentTargetWindow(ServerWindow* current_target) {
153 current_target_window_ = current_target; 184 current_target_window_ = current_target;
185
186 if (current_target_window_) {
187 // Immediately set the cursor to the last known set of operations (which
188 // could be none).
189 WindowState& state = window_state_[current_target_window_];
190 current_cursor_ = CursorForEffectBitmask(state.bitmask);
191 } else {
192 // Can't drop in empty areas.
193 current_cursor_ = static_cast<int32_t>(ui::mojom::Cursor::NO_DROP);
194 }
195
196 cursor_updater_->OnDragCursorUpdated();
154 } 197 }
155 198
156 void DragController::EnsureWindowObserved(ServerWindow* window) { 199 void DragController::EnsureWindowObserved(ServerWindow* window) {
157 if (!window) 200 if (!window)
158 return; 201 return;
159 202
160 WindowState& state = window_state_[window]; 203 WindowState& state = window_state_[window];
161 if (!state.observed) { 204 if (!state.observed) {
162 state.observed = true; 205 state.observed = true;
163 window->AddObserver(this); 206 window->AddObserver(this);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 277
235 void DragController::OnRespondToOperation(ServerWindow* window) { 278 void DragController::OnRespondToOperation(ServerWindow* window) {
236 WindowState& state = window_state_[window]; 279 WindowState& state = window_state_[window];
237 DCHECK_NE(OperationType::NONE, state.waiting_on_reply); 280 DCHECK_NE(OperationType::NONE, state.waiting_on_reply);
238 state.waiting_on_reply = OperationType::NONE; 281 state.waiting_on_reply = OperationType::NONE;
239 if (state.queued_operation.type != OperationType::NONE) 282 if (state.queued_operation.type != OperationType::NONE)
240 DispatchOperation(window, &state); 283 DispatchOperation(window, &state);
241 } 284 }
242 285
243 void DragController::OnDragStatusCompleted(const WindowId& id, 286 void DragController::OnDragStatusCompleted(const WindowId& id,
244 uint32_t bitmask) { 287 DropEffectBitmask bitmask) {
245 ServerWindow* window = source_->GetWindowById(id); 288 ServerWindow* window = source_->GetWindowById(id);
246 if (!window) { 289 if (!window) {
247 // The window has been deleted and its queue is empty. 290 // The window has been deleted and its queue is empty.
248 return; 291 return;
249 } 292 }
250 293
251 // We must remove the completed item. 294 // We must remove the completed item.
252 OnRespondToOperation(window); 295 OnRespondToOperation(window);
253 296 SetWindowDropOperations(window, bitmask);
254 // TODO(erg): |bitmask| is the allowed drag actions at the mouse location. We
255 // should use this data to change the cursor.
256 } 297 }
257 298
258 void DragController::OnDragDropCompleted(const WindowId& id, uint32_t action) { 299 void DragController::OnDragDropCompleted(const WindowId& id,
300 DropEffect action) {
259 ServerWindow* window = source_->GetWindowById(id); 301 ServerWindow* window = source_->GetWindowById(id);
260 if (!window) { 302 if (!window) {
261 // The window has been deleted after we sent the drop message. It's really 303 // The window has been deleted after we sent the drop message. It's really
262 // hard to recover from this so just signal to the source that our drag 304 // hard to recover from this so just signal to the source that our drag
263 // failed. 305 // failed.
264 MessageDragCompleted(false, ui::mojom::kDropEffectNone); 306 MessageDragCompleted(false, ui::mojom::kDropEffectNone);
265 return; 307 return;
266 } 308 }
267 309
268 OnRespondToOperation(window); 310 OnRespondToOperation(window);
269 MessageDragCompleted(action != 0u, action); 311 MessageDragCompleted(action != 0u, action);
270 } 312 }
271 313
272 void DragController::OnWindowDestroying(ServerWindow* window) { 314 void DragController::OnWindowDestroying(ServerWindow* window) {
273 auto it = window_state_.find(window); 315 auto it = window_state_.find(window);
274 if (it != window_state_.end()) { 316 if (it != window_state_.end()) {
275 window->RemoveObserver(this); 317 window->RemoveObserver(this);
276 window_state_.erase(it); 318 window_state_.erase(it);
277 } 319 }
278 320
279 if (current_target_window_ == window) 321 if (current_target_window_ == window)
280 current_target_window_ = nullptr; 322 SetCurrentTargetWindow(nullptr);
281 323
282 if (source_window_ == window) { 324 if (source_window_ == window) {
283 source_window_ = nullptr; 325 source_window_ = nullptr;
284 // Our source window is being deleted, fail the drag. 326 // Our source window is being deleted, fail the drag.
285 MessageDragCompleted(false, ui::mojom::kDropEffectNone); 327 MessageDragCompleted(false, ui::mojom::kDropEffectNone);
286 } 328 }
287 } 329 }
288 330
289 } // namespace ws 331 } // namespace ws
290 } // namespace ui 332 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698