OLD | NEW |
---|---|
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 <map> | 7 #include <map> |
8 #include <memory> | 8 #include <memory> |
9 #include <queue> | 9 #include <queue> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
13 #include "services/ui/public/interfaces/cursor/cursor.mojom.h" | 13 #include "services/ui/public/interfaces/cursor/cursor.mojom.h" |
14 #include "services/ui/ws/drag_source.h" | 14 #include "services/ui/ws/drag_source.h" |
15 #include "services/ui/ws/drag_target_connection.h" | 15 #include "services/ui/ws/drag_target_connection.h" |
16 #include "services/ui/ws/ids.h" | 16 #include "services/ui/ws/ids.h" |
17 #include "services/ui/ws/server_window.h" | 17 #include "services/ui/ws/server_window.h" |
18 #include "services/ui/ws/test_server_window_delegate.h" | 18 #include "services/ui/ws/test_server_window_delegate.h" |
19 #include "services/ui/ws/test_utils.h" | 19 #include "services/ui/ws/test_utils.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
21 #include "ui/base/cursor/cursor.h" | |
21 #include "ui/events/base_event_utils.h" | 22 #include "ui/events/base_event_utils.h" |
22 | 23 |
23 namespace ui { | 24 namespace ui { |
24 namespace ws { | 25 namespace ws { |
25 | 26 |
26 enum class QueuedType { NONE, ENTER, OVER, LEAVE, DROP }; | 27 enum class QueuedType { NONE, ENTER, OVER, LEAVE, DROP }; |
27 | 28 |
28 class DragControllerTest; | 29 class DragControllerTest; |
29 | 30 |
30 // All the classes to represent a window. | 31 // All the classes to represent a window. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 window->PerformOnDragDropStart( | 156 window->PerformOnDragDropStart( |
156 std::unordered_map<std::string, std::vector<uint8_t>>()); | 157 std::unordered_map<std::string, std::vector<uint8_t>>()); |
157 drag_operation_ = base::MakeUnique<DragController>( | 158 drag_operation_ = base::MakeUnique<DragController>( |
158 this, this, window->window(), window, MouseEvent::kMousePointerId, | 159 this, this, window->window(), window, MouseEvent::kMousePointerId, |
159 std::unordered_map<std::string, std::vector<uint8_t>>(), | 160 std::unordered_map<std::string, std::vector<uint8_t>>(), |
160 drag_operations); | 161 drag_operations); |
161 | 162 |
162 // It would be nice if we could just let the observer method fire, but it | 163 // It would be nice if we could just let the observer method fire, but it |
163 // fires during the constructor when we haven't assigned the unique_ptr | 164 // fires during the constructor when we haven't assigned the unique_ptr |
164 // yet. | 165 // yet. |
165 cursor_ = ui::mojom::CursorType(drag_operation_->current_cursor()); | 166 cursor_ = drag_operation_->current_cursor().cursor_type(); |
166 } | 167 } |
167 | 168 |
168 void DispatchDrag(DragTestWindow* window, | 169 void DispatchDrag(DragTestWindow* window, |
169 bool mouse_released, | 170 bool mouse_released, |
170 uint32_t flags, | 171 uint32_t flags, |
171 const gfx::Point& position) { | 172 const gfx::Point& position) { |
172 ui::PointerEvent event( | 173 ui::PointerEvent event( |
173 ui::MouseEvent(mouse_released ? ET_MOUSE_RELEASED : ET_MOUSE_PRESSED, | 174 ui::MouseEvent(mouse_released ? ET_MOUSE_RELEASED : ET_MOUSE_PRESSED, |
174 position, position, ui::EventTimeForNow(), flags, 0)); | 175 position, position, ui::EventTimeForNow(), flags, 0)); |
175 drag_operation_->DispatchPointerEvent(event, | 176 drag_operation_->DispatchPointerEvent(event, |
(...skipping 21 matching lines...) Expand all Loading... | |
197 | 198 |
198 DragController* drag_operation() const { return drag_operation_.get(); } | 199 DragController* drag_operation() const { return drag_operation_.get(); } |
199 | 200 |
200 const base::Optional<uint32_t>& drag_completed_action() { | 201 const base::Optional<uint32_t>& drag_completed_action() { |
201 return drag_completed_action_; | 202 return drag_completed_action_; |
202 } | 203 } |
203 const base::Optional<bool>& drag_completed_value() { | 204 const base::Optional<bool>& drag_completed_value() { |
204 return drag_completed_value_; | 205 return drag_completed_value_; |
205 } | 206 } |
206 | 207 |
207 ui::mojom::CursorType cursor() { return cursor_; } | 208 ui::CursorType cursor_type() { return cursor_; } |
sky
2017/04/26 22:16:15
() const
| |
208 | 209 |
209 private: | 210 private: |
210 // Overridden from testing::Test: | 211 // Overridden from testing::Test: |
211 void SetUp() override { | 212 void SetUp() override { |
212 testing::Test::SetUp(); | 213 testing::Test::SetUp(); |
213 | 214 |
214 window_delegate_ = base::MakeUnique<TestServerWindowDelegate>(); | 215 window_delegate_ = base::MakeUnique<TestServerWindowDelegate>(); |
215 root_window_ = | 216 root_window_ = |
216 base::MakeUnique<ServerWindow>(window_delegate_.get(), WindowId(1, 2)); | 217 base::MakeUnique<ServerWindow>(window_delegate_.get(), WindowId(1, 2)); |
217 window_delegate_->set_root_window(root_window_.get()); | 218 window_delegate_->set_root_window(root_window_.get()); |
218 root_window_->SetVisible(true); | 219 root_window_->SetVisible(true); |
219 } | 220 } |
220 | 221 |
221 void TearDown() override { | 222 void TearDown() override { |
222 drag_operation_.reset(); | 223 drag_operation_.reset(); |
223 root_window_.reset(); | 224 root_window_.reset(); |
224 window_delegate_.reset(); | 225 window_delegate_.reset(); |
225 | 226 |
226 DCHECK(server_window_by_id_.empty()); | 227 DCHECK(server_window_by_id_.empty()); |
227 DCHECK(connection_by_window_.empty()); | 228 DCHECK(connection_by_window_.empty()); |
228 | 229 |
229 testing::Test::TearDown(); | 230 testing::Test::TearDown(); |
230 } | 231 } |
231 | 232 |
232 // Overridden from DragCursorUpdater: | 233 // Overridden from DragCursorUpdater: |
233 void OnDragCursorUpdated() override { | 234 void OnDragCursorUpdated() override { |
234 if (drag_operation_) | 235 if (drag_operation_) |
235 cursor_ = ui::mojom::CursorType(drag_operation_->current_cursor()); | 236 cursor_ = drag_operation_->current_cursor().cursor_type(); |
236 } | 237 } |
237 | 238 |
238 // Overridden from DragControllerSource: | 239 // Overridden from DragControllerSource: |
239 void OnDragMoved(const gfx::Point& location) override {} | 240 void OnDragMoved(const gfx::Point& location) override {} |
240 | 241 |
241 void OnDragCompleted(bool success, uint32_t action_taken) override { | 242 void OnDragCompleted(bool success, uint32_t action_taken) override { |
242 drag_completed_action_ = action_taken; | 243 drag_completed_action_ = action_taken; |
243 drag_completed_value_ = success; | 244 drag_completed_value_ = success; |
244 } | 245 } |
245 | 246 |
246 ServerWindow* GetWindowById(const WindowId& id) override { | 247 ServerWindow* GetWindowById(const WindowId& id) override { |
247 auto it = server_window_by_id_.find(id); | 248 auto it = server_window_by_id_.find(id); |
248 if (it == server_window_by_id_.end()) | 249 if (it == server_window_by_id_.end()) |
249 return nullptr; | 250 return nullptr; |
250 return it->second; | 251 return it->second; |
251 } | 252 } |
252 | 253 |
253 DragTargetConnection* GetDragTargetForWindow( | 254 DragTargetConnection* GetDragTargetForWindow( |
254 const ServerWindow* window) override { | 255 const ServerWindow* window) override { |
255 auto it = connection_by_window_.find(const_cast<ServerWindow*>(window)); | 256 auto it = connection_by_window_.find(const_cast<ServerWindow*>(window)); |
256 if (it == connection_by_window_.end()) | 257 if (it == connection_by_window_.end()) |
257 return nullptr; | 258 return nullptr; |
258 return it->second; | 259 return it->second; |
259 } | 260 } |
260 | 261 |
261 int window_id_ = 3; | 262 int window_id_ = 3; |
262 | 263 |
263 ui::mojom::CursorType cursor_; | 264 ui::CursorType cursor_; |
264 | 265 |
265 std::map<WindowId, ServerWindow*> server_window_by_id_; | 266 std::map<WindowId, ServerWindow*> server_window_by_id_; |
266 std::map<ServerWindow*, DragTargetConnection*> connection_by_window_; | 267 std::map<ServerWindow*, DragTargetConnection*> connection_by_window_; |
267 | 268 |
268 std::unique_ptr<TestServerWindowDelegate> window_delegate_; | 269 std::unique_ptr<TestServerWindowDelegate> window_delegate_; |
269 std::unique_ptr<ServerWindow> root_window_; | 270 std::unique_ptr<ServerWindow> root_window_; |
270 | 271 |
271 std::unique_ptr<DragController> drag_operation_; | 272 std::unique_ptr<DragController> drag_operation_; |
272 | 273 |
273 base::Optional<uint32_t> drag_completed_action_; | 274 base::Optional<uint32_t> drag_completed_action_; |
274 base::Optional<bool> drag_completed_value_; | 275 base::Optional<bool> drag_completed_value_; |
275 }; | 276 }; |
276 | 277 |
277 DragTestWindow::~DragTestWindow() { | 278 DragTestWindow::~DragTestWindow() { |
278 parent_->OnTestWindowDestroyed(this); | 279 parent_->OnTestWindowDestroyed(this); |
279 } | 280 } |
280 | 281 |
281 TEST_F(DragControllerTest, SimpleDragDrop) { | 282 TEST_F(DragControllerTest, SimpleDragDrop) { |
282 std::unique_ptr<DragTestWindow> window = BuildWindow(); | 283 std::unique_ptr<DragTestWindow> window = BuildWindow(); |
283 StartDragOperation(window.get(), ui::mojom::kDropEffectMove); | 284 StartDragOperation(window.get(), ui::mojom::kDropEffectMove); |
284 | 285 |
285 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 286 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
286 | 287 |
287 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); | 288 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); |
288 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); | 289 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); |
289 window->Respond(true); | 290 window->Respond(true); |
290 | 291 |
291 // (Even though we're doing a move, the cursor name is COPY.) | 292 // (Even though we're doing a move, the cursor name is COPY.) |
292 EXPECT_EQ(ui::mojom::CursorType::kCopy, cursor()); | 293 EXPECT_EQ(ui::CursorType::kCopy, cursor_type()); |
293 | 294 |
294 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2)); | 295 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2)); |
295 EXPECT_EQ(QueuedType::OVER, window->queue_response_type()); | 296 EXPECT_EQ(QueuedType::OVER, window->queue_response_type()); |
296 window->Respond(true); | 297 window->Respond(true); |
297 | 298 |
298 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2)); | 299 DispatchDrag(window.get(), true, 0, gfx::Point(2, 2)); |
299 EXPECT_EQ(QueuedType::DROP, window->queue_response_type()); | 300 EXPECT_EQ(QueuedType::DROP, window->queue_response_type()); |
300 window->Respond(true); | 301 window->Respond(true); |
301 | 302 |
302 EXPECT_EQ(ui::mojom::kDropEffectMove, | 303 EXPECT_EQ(ui::mojom::kDropEffectMove, |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
531 EXPECT_EQ(nullptr, api.GetCurrentTarget()); | 532 EXPECT_EQ(nullptr, api.GetCurrentTarget()); |
532 | 533 |
533 // But a target window closing out from under us doesn't fail the drag. | 534 // But a target window closing out from under us doesn't fail the drag. |
534 EXPECT_FALSE(drag_completed_value().has_value()); | 535 EXPECT_FALSE(drag_completed_value().has_value()); |
535 } | 536 } |
536 | 537 |
537 TEST_F(DragControllerTest, TargetWindowClosedResetsCursor) { | 538 TEST_F(DragControllerTest, TargetWindowClosedResetsCursor) { |
538 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); | 539 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); |
539 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); | 540 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); |
540 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); | 541 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); |
541 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 542 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
542 | 543 |
543 // Send some events to |window|. | 544 // Send some events to |window|. |
544 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, | 545 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, |
545 gfx::Point(1, 1)); | 546 gfx::Point(1, 1)); |
546 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type()); | 547 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type()); |
547 window2->Respond(true); | 548 window2->Respond(true); |
548 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, | 549 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, |
549 gfx::Point(1, 1)); | 550 gfx::Point(1, 1)); |
550 window2->Respond(true); | 551 window2->Respond(true); |
551 EXPECT_EQ(ui::mojom::CursorType::kCopy, cursor()); | 552 EXPECT_EQ(ui::CursorType::kCopy, cursor_type()); |
552 | 553 |
553 // Force the destruction of |window.window|. | 554 // Force the destruction of |window.window|. |
554 window2.reset(); | 555 window2.reset(); |
555 | 556 |
556 // The cursor no loner indicates that it can drop on |window2|. | 557 // The cursor no loner indicates that it can drop on |window2|. |
557 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 558 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
558 } | 559 } |
559 | 560 |
560 TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) { | 561 TEST_F(DragControllerTest, SourceWindowClosedWhileDrag) { |
561 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); | 562 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); |
562 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); | 563 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); |
563 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); | 564 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); |
564 | 565 |
565 test::DragControllerTestApi api(drag_operation()); | 566 test::DragControllerTestApi api(drag_operation()); |
566 | 567 |
567 // Send some events to |windoww|. | 568 // Send some events to |windoww|. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
633 // Ignore events from pointer 5. | 634 // Ignore events from pointer 5. |
634 DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON, | 635 DispatchDragWithPointer(window.get(), 5, false, ui::EF_LEFT_MOUSE_BUTTON, |
635 gfx::Point(1, 1)); | 636 gfx::Point(1, 1)); |
636 ASSERT_EQ(0u, window->queue_size()); | 637 ASSERT_EQ(0u, window->queue_size()); |
637 } | 638 } |
638 | 639 |
639 TEST_F(DragControllerTest, RejectingWindowHasProperCursor) { | 640 TEST_F(DragControllerTest, RejectingWindowHasProperCursor) { |
640 std::unique_ptr<DragTestWindow> window = BuildWindow(); | 641 std::unique_ptr<DragTestWindow> window = BuildWindow(); |
641 StartDragOperation(window.get(), ui::mojom::kDropEffectMove); | 642 StartDragOperation(window.get(), ui::mojom::kDropEffectMove); |
642 | 643 |
643 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 644 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
644 | 645 |
645 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); | 646 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(1, 1)); |
646 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); | 647 EXPECT_EQ(QueuedType::ENTER, window->queue_response_type()); |
647 window->Respond(true); | 648 window->Respond(true); |
648 | 649 |
649 EXPECT_EQ(ui::mojom::CursorType::kCopy, cursor()); | 650 EXPECT_EQ(ui::CursorType::kCopy, cursor_type()); |
650 | 651 |
651 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2)); | 652 DispatchDrag(window.get(), false, ui::EF_LEFT_MOUSE_BUTTON, gfx::Point(2, 2)); |
652 EXPECT_EQ(QueuedType::OVER, window->queue_response_type()); | 653 EXPECT_EQ(QueuedType::OVER, window->queue_response_type()); |
653 | 654 |
654 // At this point, we respond with no available drag actions at this pixel. | 655 // At this point, we respond with no available drag actions at this pixel. |
655 window->Respond(false); | 656 window->Respond(false); |
656 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 657 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
657 } | 658 } |
658 | 659 |
659 TEST_F(DragControllerTest, ResopnseFromOtherWindowDoesntChangeCursor) { | 660 TEST_F(DragControllerTest, ResopnseFromOtherWindowDoesntChangeCursor) { |
660 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); | 661 std::unique_ptr<DragTestWindow> window1 = BuildWindow(); |
661 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); | 662 std::unique_ptr<DragTestWindow> window2 = BuildWindow(); |
662 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); | 663 StartDragOperation(window1.get(), ui::mojom::kDropEffectMove); |
663 | 664 |
664 // Send some events to |window2|. | 665 // Send some events to |window2|. |
665 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, | 666 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, |
666 gfx::Point(1, 1)); | 667 gfx::Point(1, 1)); |
667 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type()); | 668 EXPECT_EQ(QueuedType::ENTER, window2->queue_response_type()); |
668 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, | 669 DispatchDrag(window2.get(), false, ui::EF_LEFT_MOUSE_BUTTON, |
669 gfx::Point(1, 1)); | 670 gfx::Point(1, 1)); |
670 | 671 |
671 EXPECT_EQ(ui::mojom::CursorType::kNoDrop, cursor()); | 672 EXPECT_EQ(ui::CursorType::kNoDrop, cursor_type()); |
672 | 673 |
673 // Now enter |window1|, and respond. | 674 // Now enter |window1|, and respond. |
674 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON, | 675 DispatchDrag(window1.get(), false, ui::EF_LEFT_MOUSE_BUTTON, |
675 gfx::Point(5, 5)); | 676 gfx::Point(5, 5)); |
676 EXPECT_EQ(QueuedType::ENTER, window1->queue_response_type()); | 677 EXPECT_EQ(QueuedType::ENTER, window1->queue_response_type()); |
677 window1->Respond(true); | 678 window1->Respond(true); |
678 | 679 |
679 EXPECT_EQ(ui::mojom::CursorType::kCopy, cursor()); | 680 EXPECT_EQ(ui::CursorType::kCopy, cursor_type()); |
680 | 681 |
681 // Window 2 responding negatively to its queued messages shouldn't change the | 682 // Window 2 responding negatively to its queued messages shouldn't change the |
682 // cursor. | 683 // cursor. |
683 window2->Respond(false); | 684 window2->Respond(false); |
684 | 685 |
685 EXPECT_EQ(ui::mojom::CursorType::kCopy, cursor()); | 686 EXPECT_EQ(ui::CursorType::kCopy, cursor_type()); |
686 } | 687 } |
687 | 688 |
688 } // namespace ws | 689 } // namespace ws |
689 } // namespace ui | 690 } // namespace ui |
OLD | NEW |