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

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

Issue 2266603002: mus: Implement interwindow drag and drop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Clear the implicit pointer drags before start. Created 4 years, 3 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
(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 "services/ui/ws/drag_controller.h"
6 #include "services/ui/ws/drag_source.h"
7 #include "services/ui/ws/drag_target_connection.h"
8 #include "services/ui/ws/ids.h"
9 #include "services/ui/ws/server_window.h"
10 #include "services/ui/ws/test_server_window_delegate.h"
11 #include "services/ui/ws/test_utils.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/events/base_event_utils.h"
14
15 namespace ui {
16 namespace ws {
17
18 enum class QueuedType { NONE, ENTER, OVER, LEAVE, DROP };
19
20 class DragControllerTest;
21
22 // All the classes to represent a window.
23 class DragTestWindow : public DragTargetConnection {
24 public:
25 struct DragEvent {
26 QueuedType type;
27 uint32_t key_state;
28 gfx::Point cursor_offset;
29 uint32_t effect_bitmask;
30 base::Callback<void(uint32_t)> callback;
31 };
32
33 DragTestWindow(DragControllerTest* parent, const WindowId& id)
34 : parent_(parent), window_delegate_(), window_(&window_delegate_, id) {
35 window_.SetCanAcceptDrops(true);
36 }
37 ~DragTestWindow() override;
38
39 TestServerWindowDelegate* delegate() { return &window_delegate_; }
40 ServerWindow* window() { return &window_; }
41
42 QueuedType queue_response_type() {
43 if (queued_callbacks_.empty())
44 return QueuedType::NONE;
45 return queued_callbacks_.front().type;
46 }
47
48 const DragEvent& queue_front() { return queued_callbacks_.front(); }
49
50 size_t queue_size() { return queued_callbacks_.size(); }
51
52 uint32_t times_received_drag_start() { return times_received_drag_start_; }
53
54 void SetParent(DragTestWindow* p) { p->window_.Add(&window_); }
55
56 void OptOutOfDrag() { window_.SetCanAcceptDrops(false); }
57
58 // Calls the callback at the front of the queue.
59 void Respond(bool respond_with_effect) {
60 if (queued_callbacks_.size()) {
61 if (!queued_callbacks_.front().callback.is_null()) {
62 queued_callbacks_.front().callback.Run(
63 respond_with_effect ? queued_callbacks_.front().effect_bitmask : 0);
64 }
65
66 queued_callbacks_.pop();
67 }
68 }
69
70 // Overridden from DragTestConnection:
71 void PerformOnDragStart(
72 const ServerWindow* window,
73 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data) override {
74 times_received_drag_start_++;
75 mime_data_ = std::move(mime_data);
76 }
77
78 void PerformOnDragEnter(
79 const ServerWindow* window,
80 uint32_t key_state,
81 const gfx::Point& cursor_offset,
82 uint32_t effect_bitmask,
83 const base::Callback<void(uint32_t)>& callback) override {
84 DCHECK_EQ(window, &window_);
85 queued_callbacks_.push({QueuedType::ENTER, key_state, cursor_offset,
86 effect_bitmask, callback});
87 }
88
89 void PerformOnDragOver(
90 const ServerWindow* window,
91 uint32_t key_state,
92 const gfx::Point& cursor_offset,
93 uint32_t effect_bitmask,
94 const base::Callback<void(uint32_t)>& callback) override {
95 DCHECK_EQ(window, &window_);
96 queued_callbacks_.push(
97 {QueuedType::OVER, key_state, cursor_offset, effect_bitmask, callback});
98 }
99
100 void PerformOnDragLeave(const ServerWindow* window) override {
101 DCHECK_EQ(window, &window_);
102 queued_callbacks_.push({QueuedType::LEAVE, 0, gfx::Point(), 0,
103 base::Callback<void(uint32_t)>()});
104 }
105
106 void PerformOnDragDrop(
107 const ServerWindow* window,
108 uint32_t key_state,
109 const gfx::Point& cursor_offset,
110 uint32_t effect_bitmask,
111 const base::Callback<void(uint32_t)>& callback) override {
112 DCHECK_EQ(window, &window_);
113 queued_callbacks_.push(
114 {QueuedType::DROP, key_state, cursor_offset, effect_bitmask, callback});
115 }
116
117 void PerformOnDragFinish(const ServerWindow* window) override {
118 mime_data_.SetToEmpty();
119 }
120
121 private:
122 DragControllerTest* parent_;
123 TestServerWindowDelegate window_delegate_;
124 ServerWindow window_;
125 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data_;
126 uint32_t times_received_drag_start_ = 0;
127
128 std::queue<DragEvent> queued_callbacks_;
129 };
130
131 class DragControllerTest : public testing::Test, public DragSource {
132 public:
133 std::unique_ptr<DragTestWindow> BuildWindow() {
134 WindowId id(1, ++window_id_);
135 std::unique_ptr<DragTestWindow> p =
136 base::MakeUnique<DragTestWindow>(this, id);
137 server_window_by_id_[id] = p->window();
138 connection_by_window_[p->window()] = p.get();
139 return p;
140 }
141
142 void StartDragOperation(
143 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data,
144 DragTestWindow* window,
145 uint32_t drag_operations) {
146 window->PerformOnDragStart(window->window(), mime_data.Clone());
147 drag_operation_.reset(new DragController(
148 this, window->window(), PointerEvent::kMousePointerId,
149 std::move(mime_data), drag_operations));
150 }
151
152 void DispatchDrag(DragTestWindow* window,
153 bool mouse_released,
154 uint32_t flags,
155 const gfx::Point& position) {
156 ui::PointerEvent event(
157 ui::MouseEvent(mouse_released ? ET_MOUSE_RELEASED : ET_MOUSE_PRESSED,
158 position, position, ui::EventTimeForNow(), flags, 0));
159 drag_operation_->DispatchPointerEvent(event,
160 window ? window->window() : nullptr);
161 }
162
163 void DispatchDragWithPointer(DragTestWindow* window,
164 int32_t drag_pointer,
165 bool mouse_released,
166 uint32_t flags,
167 const gfx::Point& position) {
168 ui::PointerEvent event(ET_POINTER_DOWN, position, position, flags,
169 drag_pointer, 0, PointerDetails(),
170 base::TimeTicks());
171 drag_operation_->DispatchPointerEvent(event,
172 window ? window->window() : nullptr);
173 }
174
175 void OnTestWindowDestroyed(DragTestWindow* test_window) {
176 server_window_by_id_.erase(test_window->window()->id());
177 connection_by_window_.erase(test_window->window());
178 }
179
180 DragController* drag_operation() const { return drag_operation_.get(); }
181 const base::Optional<bool>& drag_completed_value() {
182 return drag_completed_value_;
183 }
184
185 private:
186 // Overridden from testing::Test:
187 void SetUp() override {
188 testing::Test::SetUp();
189
190 window_delegate_.reset(new TestServerWindowDelegate());
191 root_window_.reset(
192 new ServerWindow(window_delegate_.get(), WindowId(1, 2)));
193 window_delegate_->set_root_window(root_window_.get());
194 root_window_->SetVisible(true);
195 }
196
197 void TearDown() override {
198 drag_operation_.reset();
199 root_window_.reset();
200 window_delegate_.reset();
201
202 DCHECK(server_window_by_id_.empty());
203 DCHECK(connection_by_window_.empty());
204
205 testing::Test::TearDown();
206 }
207
208 // Overridden from DragControllerSource:
209 void OnDragCompleted(bool success) override {
210 drag_completed_value_ = success;
211 }
212
213 ServerWindow* GetWindowById(const WindowId& id) override {
214 auto it = server_window_by_id_.find(id);
215 if (it == server_window_by_id_.end())
216 return nullptr;
217 return it->second;
218 }
219
220 DragTargetConnection* GetDragTargetWithRoot(
221 const ServerWindow* window) override {
222 auto it = connection_by_window_.find(const_cast<ServerWindow*>(window));
223 if (it == connection_by_window_.end())
224 return nullptr;
225 return it->second;
226 }
227
228 int window_id_ = 3;
229
230 std::map<WindowId, ServerWindow*> server_window_by_id_;
231 std::map<ServerWindow*, DragTargetConnection*> connection_by_window_;
232
233 std::unique_ptr<TestServerWindowDelegate> window_delegate_;
234 std::unique_ptr<ServerWindow> root_window_;
235
236 std::unique_ptr<DragController> drag_operation_;
237
238 base::Optional<bool> drag_completed_value_;
239 };
240
241 DragTestWindow::~DragTestWindow() {
242 parent_->OnTestWindowDestroyed(this);
243 }
244
245 TEST_F(DragControllerTest, SimpleDragDrop) {
246 std::unique_ptr<DragTestWindow> window = BuildWindow();
247 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
248 StartDragOperation(std::move(mime_data), window.get(),
249 ui::mojom::kDropEffectMove);
250
251 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
252 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
253 window->Respond(true);
254
255 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
256 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
257 window->Respond(true);
258
259 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2));
260 EXPECT_EQ(QueuedType::DROP, window->queue_response_type());
261 window->Respond(true);
262
263 EXPECT_TRUE(drag_completed_value().value_or(false));
264 }
265
266 TEST_F(DragControllerTest, OnlyDeliverMimeDataOnce) {
267 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
268 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
269 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
270
271 // The client lib is responsible for sending the data to the window that's
272 // the drag source to minimize IPC.
273 EXPECT_EQ(0u, window1->times_received_drag_start());
274 StartDragOperation(std::move(mime_data), window1.get(),
275 ui::mojom::kDropEffectMove);
276 EXPECT_EQ(1u, window1->times_received_drag_start());
277 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
278 gfx::Point(1, 1));
279 EXPECT_EQ(1u, window1->times_received_drag_start());
280 window1->Respond(true);
281
282 // Window2 doesn't receive the drag data until mouse is over it.
283 EXPECT_EQ(0u, window2->times_received_drag_start());
284 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
285 gfx::Point(2, 2));
286 EXPECT_EQ(1u, window2->times_received_drag_start());
287
288 // Moving back to the source window doesn't send an additional start message.
289 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
290 gfx::Point(1, 1));
291 EXPECT_EQ(1u, window1->times_received_drag_start());
292
293 // Moving back to window2 doesn't send an additional start message.
294 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
295 gfx::Point(1, 1));
296 EXPECT_EQ(1u, window2->times_received_drag_start());
297 }
298
299 TEST_F(DragControllerTest, DeliverMessageToParent) {
300 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
301 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
302 std::unique_ptr<DragTestWindow> window3 = BuildWindow();
303 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
304
305 window3->SetParent(window2.get());
306 window3->OptOutOfDrag();
307
308 StartDragOperation(std::move(mime_data), window1.get(),
309 ui::mojom::kDropEffectMove);
310
311 // Dispatching a drag to window3 (which has can accept drags off) redirects
312 // to window2, which is its parent.
313 DispatchDrag(window3.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
314 gfx::Point(1, 1));
315 EXPECT_EQ(1u, window2->times_received_drag_start());
316 }
317
318 TEST_F(DragControllerTest, FailWhenDropOverNoWindow) {
319 std::unique_ptr<DragTestWindow> window = BuildWindow();
320 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
321 StartDragOperation(std::move(mime_data), window.get(),
322 ui::mojom::kDropEffectMove);
323
324 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
325 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
326 window->Respond(true);
327
328 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
329 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
330 window->Respond(true);
331
332 DispatchDrag(nullptr, true, 0, gfx::Point(2, 2));
333 // Moving outside of |window| should result in |window| getting a leave.
334 EXPECT_EQ(QueuedType::LEAVE, window->queue_response_type());
335 window->Respond(true);
336
337 EXPECT_FALSE(drag_completed_value().value_or(true));
338 }
339
340 TEST_F(DragControllerTest, EnterLeaveWhenMovingBetweenTwoWindows) {
341 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
342 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
343 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
344 StartDragOperation(std::move(mime_data), window1.get(),
345 ui::mojom::kDropEffectMove);
346
347 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
348 gfx::Point(1, 1));
349 EXPECT_EQ(QueuedType::ENTER, window1->queue_response_type());
350 window1->Respond(true);
351
352 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
353 gfx::Point(2, 2));
354 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
355 EXPECT_EQ(QueuedType::LEAVE, window1->queue_response_type());
356 window1->Respond(true);
357 window2->Respond(true);
358 }
359
360 TEST_F(DragControllerTest, EnterToOverQueued) {
361 std::unique_ptr<DragTestWindow> window = BuildWindow();
362 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
363 StartDragOperation(std::move(mime_data), window.get(),
364 ui::mojom::kDropEffectMove);
365
366 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
367 ASSERT_EQ(1u, window->queue_size());
368 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
369 // Don't respond.
370
371 // We don't receive another message since we haven't acknowledged the first.
372 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 2));
373 ASSERT_EQ(1u, window->queue_size());
374
375 // Responding causes us to receive our next event.
376 window->Respond(true);
377 ASSERT_EQ(1u, window->queue_size());
378 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
379 }
380
381 TEST_F(DragControllerTest, CoalesceMouseOverEvents) {
382 std::unique_ptr<DragTestWindow> window = BuildWindow();
383 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
384 StartDragOperation(std::move(mime_data), window.get(),
385 ui::mojom::kDropEffectMove);
386
387 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
388 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
389
390 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 2));
391 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
392 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 3));
393
394 // Responding to the first delivers us the last mouse over event's position.
395 window->Respond(true);
396 ASSERT_EQ(1u, window->queue_size());
397 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
398 EXPECT_EQ(gfx::Point(2, 3), window->queue_front().cursor_offset);
399
400 // There are no queued events because they were coalesced.
401 window->Respond(true);
402 EXPECT_EQ(0u, window->queue_size());
403 }
404
405 TEST_F(DragControllerTest, RemovePendingMouseOversOnLeave) {
406 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
407 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
408 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
409 StartDragOperation(std::move(mime_data), window1.get(),
410 ui::mojom::kDropEffectMove);
411
412 // Enter
413 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
414 gfx::Point(1, 1));
415 EXPECT_EQ(QueuedType::ENTER, window1->queue_response_type());
416
417 // Over
418 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
419 gfx::Point(1, 1));
420
421 // Leave
422 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
423 gfx::Point(1, 1));
424
425 // The window finally responds to the enter message; we should not receive
426 // any over messages since we didn't respond to the enter message in time.
427 window1->Respond(true);
428 ASSERT_EQ(1u, window1->queue_size());
429 EXPECT_EQ(QueuedType::LEAVE, window1->queue_response_type());
430 }
431
432 TEST_F(DragControllerTest, TargetWindowClosedWhileDrag) {
433 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
434 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
435 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
436 StartDragOperation(std::move(mime_data), window1.get(),
437 ui::mojom::kDropEffectMove);
438
439 test::DragControllerTestApi api(drag_operation());
440
441 // Send some events to |window|.
442 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
443 gfx::Point(1, 1));
444 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
445 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
446 gfx::Point(1, 1));
447
448 ServerWindow* server_window = window2->window();
449
450 // Ensure that DragController is waiting for a response from |window|.
451 EXPECT_EQ(2u, api.GetSizeOfQueueForWindow(server_window));
452 EXPECT_EQ(server_window, api.GetCurrentTarget());
453
454 // Force the destruction of |window.window|.
455 window2.reset();
456
457 // DragController doesn't know anything about the server window now.
458 EXPECT_EQ(0u, api.GetSizeOfQueueForWindow(server_window));
459 EXPECT_EQ(nullptr, api.GetCurrentTarget());
460
461 // But a target window closing out from under us doesn't fail the drag.
462 EXPECT_FALSE(drag_completed_value().has_value());
463 }
464
465 TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) {
466 std::unique_ptr<DragTestWindow> window1 = BuildWindow();
467 std::unique_ptr<DragTestWindow> window2 = BuildWindow();
468 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
469 StartDragOperation(std::move(mime_data), window1.get(),
470 ui::mojom::kDropEffectMove);
471
472 test::DragControllerTestApi api(drag_operation());
473
474 // Send some events to |window|.
475 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
476 gfx::Point(1, 1));
477 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type());
478 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON,
479 gfx::Point(1, 1));
480
481 ServerWindow* server_window = window2->window();
482
483 // Ensure that DragController is waiting for a response from |window|.
484 EXPECT_EQ(2u, api.GetSizeOfQueueForWindow(server_window));
485 EXPECT_EQ(server_window, api.GetCurrentTarget());
486
487 // Force the destruction of the source window.
488 window1.reset();
489
490 // The source window going away fails the drag.
491 EXPECT_FALSE(drag_completed_value().value_or(true));
492 }
493
494 TEST_F(DragControllerTest, DontQueueEventsAfterDrop) {
495 // The DragController needs to stick around to coordinate the drop, but
496 // it should ignore further mouse events during this time.
497 std::unique_ptr<DragTestWindow> window = BuildWindow();
498 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
499 StartDragOperation(std::move(mime_data), window.get(),
500 ui::mojom::kDropEffectMove);
501
502 test::DragControllerTestApi api(drag_operation());
503
504 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
505 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
506 window->Respond(true);
507
508 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
509 EXPECT_EQ(QueuedType::OVER, window->queue_response_type());
510 window->Respond(true);
511
512 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2));
513 EXPECT_EQ(QueuedType::DROP, window->queue_response_type());
514 EXPECT_EQ(1u, api.GetSizeOfQueueForWindow(window->window()));
515
516 // Further located events don't result in additional drag messages.
517 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
518 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2));
519 EXPECT_EQ(1u, api.GetSizeOfQueueForWindow(window->window()));
520 }
521
522 TEST_F(DragControllerTest, CancelDrag) {
523 // The DragController needs to stick around to coordinate the drop, but
524 // it should ignore further mouse events during this time.
525 std::unique_ptr<DragTestWindow> window = BuildWindow();
526 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
527 StartDragOperation(std::move(mime_data), window.get(),
528 ui::mojom::kDropEffectMove);
529
530 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1));
531 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type());
532 window->Respond(true);
533
534 drag_operation()->Cancel();
535
536 EXPECT_FALSE(drag_completed_value().value_or(true));
537 }
538
539 TEST_F(DragControllerTest, IgnoreEventsFromOtherPointers) {
540 std::unique_ptr<DragTestWindow> window = BuildWindow();
541 mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data;
542 // This starts the operation with PointerEvent::kMousePointerId.
543 StartDragOperation(std::move(mime_data), window.get(),
544 ui::mojom::kDropEffectMove);
545
546 // Ignore events from pointer 5.
547 DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON,
548 gfx::Point(1, 1));
549 ASSERT_EQ(0u, window->queue_size());
550 }
551
552 // TODO(erg): Add a test to ensure windows that the cursor isn't over
553 // responding to messages don't change the cursor when we have cursor handling
554 // code.
555
556 } // namespace ws
557 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698