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

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

Issue 2680883002: Fixes bugs in cursor handling (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « services/ui/ws/window_server.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/window_tree.h" 5 #include "services/ui/ws/window_tree.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 126
127 class WindowTreeTest : public testing::Test { 127 class WindowTreeTest : public testing::Test {
128 public: 128 public:
129 WindowTreeTest() {} 129 WindowTreeTest() {}
130 ~WindowTreeTest() override {} 130 ~WindowTreeTest() override {}
131 131
132 ui::mojom::Cursor cursor_id() { 132 ui::mojom::Cursor cursor_id() {
133 return window_event_targeting_helper_.cursor(); 133 return window_event_targeting_helper_.cursor();
134 } 134 }
135 Display* display() { return window_event_targeting_helper_.display(); } 135 Display* display() { return window_event_targeting_helper_.display(); }
136 TestWindowTreeBinding* last_binding() {
137 return window_event_targeting_helper_.last_binding();
138 }
139 TestWindowTreeClient* last_window_tree_client() { 136 TestWindowTreeClient* last_window_tree_client() {
140 return window_event_targeting_helper_.last_window_tree_client(); 137 return window_event_targeting_helper_.last_window_tree_client();
141 } 138 }
142 TestWindowTreeClient* wm_client() { 139 TestWindowTreeClient* wm_client() {
143 return window_event_targeting_helper_.wm_client(); 140 return window_event_targeting_helper_.wm_client();
144 } 141 }
145 WindowServer* window_server() { 142 WindowServer* window_server() {
146 return window_event_targeting_helper_.window_server(); 143 return window_event_targeting_helper_.window_server();
147 } 144 }
148 WindowTree* wm_tree() { 145 WindowTree* wm_tree() {
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) { 466 TEST_F(WindowTreeTest, CursorChangesWhenMouseOverWindowAndWindowSetsCursor) {
470 TestWindowTreeClient* embed_client = nullptr; 467 TestWindowTreeClient* embed_client = nullptr;
471 WindowTree* tree = nullptr; 468 WindowTree* tree = nullptr;
472 ServerWindow* window = nullptr; 469 ServerWindow* window = nullptr;
473 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window)); 470 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
474 471
475 // Like in BasicInputEventTarget, we send a pointer down event to be 472 // Like in BasicInputEventTarget, we send a pointer down event to be
476 // dispatched. This is only to place the mouse cursor over that window though. 473 // dispatched. This is only to place the mouse cursor over that window though.
477 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); 474 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
478 475
479 window->SetPredefinedCursor(mojom::Cursor::IBEAM); 476 // Set the cursor on the parent as that is where the cursor is picked up from.
477 window->parent()->SetPredefinedCursor(mojom::Cursor::IBEAM);
480 478
481 // Because the cursor is over the window when SetCursor was called, we should 479 // Because the cursor is over the window when SetCursor was called, we should
482 // have immediately changed the cursor. 480 // have immediately changed the cursor.
483 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 481 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
484 } 482 }
485 483
486 TEST_F(WindowTreeTest, CursorChangesWhenEnteringWindowWithDifferentCursor) { 484 TEST_F(WindowTreeTest, CursorChangesWhenEnteringWindowWithDifferentCursor) {
487 TestWindowTreeClient* embed_client = nullptr; 485 TestWindowTreeClient* embed_client = nullptr;
488 WindowTree* tree = nullptr; 486 WindowTree* tree = nullptr;
489 ServerWindow* window = nullptr; 487 ServerWindow* window = nullptr;
490 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window)); 488 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
491 489
492 // Let's create a pointer event outside the window and then move the pointer 490 // Let's create a pointer event outside the window and then move the pointer
493 // inside. 491 // inside.
494 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); 492 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
495 window->SetPredefinedCursor(mojom::Cursor::IBEAM); 493 // Set the cursor on the parent as that is where the cursor is picked up from.
494 window->parent()->SetPredefinedCursor(mojom::Cursor::IBEAM);
496 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id()); 495 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id());
497 496
498 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); 497 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
499 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 498 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
500 } 499 }
501 500
502 TEST_F(WindowTreeTest, TouchesDontChangeCursor) { 501 TEST_F(WindowTreeTest, TouchesDontChangeCursor) {
503 TestWindowTreeClient* embed_client = nullptr; 502 TestWindowTreeClient* embed_client = nullptr;
504 WindowTree* tree = nullptr; 503 WindowTree* tree = nullptr;
505 ServerWindow* window = nullptr; 504 ServerWindow* window = nullptr;
(...skipping 12 matching lines...) Expand all
518 517
519 TEST_F(WindowTreeTest, DragOutsideWindow) { 518 TEST_F(WindowTreeTest, DragOutsideWindow) {
520 TestWindowTreeClient* embed_client = nullptr; 519 TestWindowTreeClient* embed_client = nullptr;
521 WindowTree* tree = nullptr; 520 WindowTree* tree = nullptr;
522 ServerWindow* window = nullptr; 521 ServerWindow* window = nullptr;
523 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window)); 522 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
524 523
525 // Start with the cursor outside the window. Setting the cursor shouldn't 524 // Start with the cursor outside the window. Setting the cursor shouldn't
526 // change the cursor. 525 // change the cursor.
527 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); 526 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
528 window->SetPredefinedCursor(mojom::Cursor::IBEAM); 527 // Set the cursor on the parent as that is where the cursor is picked up from.
528 window->parent()->SetPredefinedCursor(mojom::Cursor::IBEAM);
529 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id()); 529 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id());
530 530
531 // Move the pointer to the inside of the window 531 // Move the pointer to the inside of the window
532 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22)); 532 DispatchEventAndAckImmediately(CreateMouseMoveEvent(21, 22));
533 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 533 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
534 534
535 // Start the drag. 535 // Start the drag.
536 DispatchEventAndAckImmediately(CreateMouseDownEvent(21, 22)); 536 DispatchEventAndAckImmediately(CreateMouseDownEvent(21, 22));
537 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 537 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
538 538
539 // Move the cursor (mouse is still down) outside the window. 539 // Move the cursor (mouse is still down) outside the window.
540 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5)); 540 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
541 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 541 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
542 542
543 // Release the cursor. We should now adapt the cursor of the window 543 // Release the cursor. We should now adapt the cursor of the window
544 // underneath the pointer. 544 // underneath the pointer.
545 DispatchEventAndAckImmediately(CreateMouseUpEvent(5, 5)); 545 DispatchEventAndAckImmediately(CreateMouseUpEvent(5, 5));
546 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); 546 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id());
547 } 547 }
548 548
549 TEST_F(WindowTreeTest, ChangingWindowBoundsChangesCursor) { 549 TEST_F(WindowTreeTest, ChangingWindowBoundsChangesCursor) {
550 TestWindowTreeClient* embed_client = nullptr; 550 TestWindowTreeClient* embed_client = nullptr;
551 WindowTree* tree = nullptr; 551 WindowTree* tree = nullptr;
552 ServerWindow* window = nullptr; 552 ServerWindow* window = nullptr;
553 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window)); 553 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window));
554 554
555 // Put the cursor just outside the bounds of the window. 555 // Put the cursor just outside the bounds of the window.
556 DispatchEventAndAckImmediately(CreateMouseMoveEvent(41, 41)); 556 DispatchEventAndAckImmediately(CreateMouseMoveEvent(41, 41));
557 window->SetPredefinedCursor(mojom::Cursor::IBEAM); 557 // Sets the cursor on the root as that is where the cursor is picked up from.
558 window->parent()->SetPredefinedCursor(mojom::Cursor::IBEAM);
558 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id()); 559 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id());
559 560
560 // Expand the bounds of the window so they now include where the cursor now 561 // Expand the bounds of the window so they now include where the cursor now
561 // is. 562 // is.
562 window->SetBounds(gfx::Rect(20, 20, 25, 25)); 563 window->SetBounds(gfx::Rect(20, 20, 25, 25));
563 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 564 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
564 565
565 // Contract the bounds again. 566 // Contract the bounds again.
566 window->SetBounds(gfx::Rect(20, 20, 20, 20)); 567 window->SetBounds(gfx::Rect(20, 20, 20, 20));
567 EXPECT_EQ(mojom::Cursor::CURSOR_NULL, cursor_id()); 568 EXPECT_EQ(mojom::Cursor::POINTER, cursor_id());
568 } 569 }
569 570
570 TEST_F(WindowTreeTest, WindowReorderingChangesCursor) { 571 TEST_F(WindowTreeTest, WindowReorderingChangesCursor) {
571 TestWindowTreeClient* embed_client = nullptr; 572 // Setup two trees parented to the root with the same bounds.
572 WindowTree* tree = nullptr; 573 ServerWindow* embed_window1 =
573 ServerWindow* window1 = nullptr; 574 window_event_targeting_helper_.CreatePrimaryTree(
574 EXPECT_NO_FATAL_FAILURE(SetupEventTargeting(&embed_client, &tree, &window1)); 575 gfx::Rect(0, 0, 200, 200), gfx::Rect(0, 0, 50, 50));
576 ServerWindow* embed_window2 =
577 window_event_targeting_helper_.CreatePrimaryTree(
578 gfx::Rect(0, 0, 200, 200), gfx::Rect(0, 0, 50, 50));
575 579
576 // Create a second window right over the first. 580 ASSERT_EQ(embed_window1->parent(), embed_window2->parent());
577 const ClientWindowId embed_window_id(FirstRootId(tree)); 581 embed_window1->set_event_targeting_policy(
578 const ClientWindowId child2_id(BuildClientWindowId(tree, 2)); 582 mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
579 EXPECT_TRUE(tree->NewWindow(child2_id, ServerWindow::Properties())); 583 embed_window2->set_event_targeting_policy(
580 ServerWindow* child2 = tree->GetWindowByClientId(child2_id); 584 mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
581 ASSERT_TRUE(child2); 585 embed_window1->SetPredefinedCursor(mojom::Cursor::IBEAM);
582 EXPECT_TRUE(tree->AddWindow(embed_window_id, child2_id)); 586 embed_window2->SetPredefinedCursor(mojom::Cursor::CROSS);
583 child2->SetVisible(true); 587 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
584 child2->SetBounds(gfx::Rect(20, 20, 20, 20)); 588 // Cursor should match that of top-most window, which is |embed_window2|.
585 589 EXPECT_EQ(mojom::Cursor::CROSS, cursor_id());
586 // Give each window a different cursor. 590 // Move |embed_window1| on top, cursor should now match it.
587 window1->SetPredefinedCursor(mojom::Cursor::IBEAM); 591 embed_window1->parent()->StackChildAtTop(embed_window1);
588 child2->SetPredefinedCursor(mojom::Cursor::HAND);
589
590 // We expect window2 to be over window1 now.
591 DispatchEventAndAckImmediately(CreateMouseMoveEvent(22, 22));
592 EXPECT_EQ(mojom::Cursor::HAND, cursor_id());
593
594 // But when we put window2 at the bottom, we should adapt window1's cursor.
595 child2->parent()->StackChildAtBottom(child2);
596 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id()); 592 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
597 } 593 }
598 594
595 // Assertions around moving cursor between trees with roots.
596 TEST_F(WindowTreeTest, CursorMultipleTrees) {
597 // Setup two trees parented to the root with the same bounds.
598 ServerWindow* embed_window1 =
599 window_event_targeting_helper_.CreatePrimaryTree(
600 gfx::Rect(0, 0, 200, 200), gfx::Rect(0, 0, 10, 10));
601 ServerWindow* embed_window2 =
602 window_event_targeting_helper_.CreatePrimaryTree(
603 gfx::Rect(0, 0, 200, 200), gfx::Rect(20, 20, 20, 20));
604 embed_window1->set_event_targeting_policy(
605 mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
606 embed_window2->set_event_targeting_policy(
607 mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
608 embed_window2->parent()->set_event_targeting_policy(
609 mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
610 embed_window1->SetPredefinedCursor(mojom::Cursor::IBEAM);
611 embed_window2->SetPredefinedCursor(mojom::Cursor::CROSS);
612 embed_window1->parent()->SetPredefinedCursor(mojom::Cursor::COPY);
613
614 // Create a child of |embed_window1|.
615 ServerWindow* embed_window1_child = NewWindowInTreeWithParent(
616 window_server()->GetTreeWithRoot(embed_window1), embed_window1);
617 ASSERT_TRUE(embed_window1_child);
618 embed_window1_child->SetBounds(gfx::Rect(0, 0, 10, 10));
619 embed_window1_child->SetVisible(true);
620
621 // Move mouse into |embed_window1|.
622 DispatchEventAndAckImmediately(CreateMouseMoveEvent(5, 5));
623 EXPECT_EQ(mojom::Cursor::IBEAM, cursor_id());
624
625 // Move mouse into |embed_window2|.
626 DispatchEventAndAckImmediately(CreateMouseMoveEvent(25, 25));
627 EXPECT_EQ(mojom::Cursor::CROSS, cursor_id());
628
629 // Move mouse into area between, which should use cursor set on parent.
630 DispatchEventAndAckImmediately(CreateMouseMoveEvent(15, 15));
631 EXPECT_EQ(mojom::Cursor::COPY, cursor_id());
632 }
633
599 TEST_F(WindowTreeTest, EventAck) { 634 TEST_F(WindowTreeTest, EventAck) {
600 const ClientWindowId embed_window_id = BuildClientWindowId(wm_tree(), 1); 635 const ClientWindowId embed_window_id = BuildClientWindowId(wm_tree(), 1);
601 EXPECT_TRUE( 636 EXPECT_TRUE(
602 wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties())); 637 wm_tree()->NewWindow(embed_window_id, ServerWindow::Properties()));
603 EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true)); 638 EXPECT_TRUE(wm_tree()->SetWindowVisibility(embed_window_id, true));
604 ASSERT_TRUE(FirstRoot(wm_tree())); 639 ASSERT_TRUE(FirstRoot(wm_tree()));
605 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id)); 640 EXPECT_TRUE(wm_tree()->AddWindow(FirstRootId(wm_tree()), embed_window_id));
606 ASSERT_EQ(1u, display()->root_window()->children().size()); 641 ASSERT_EQ(1u, display()->root_window()->children().size());
607 ServerWindow* wm_root = FirstRoot(wm_tree()); 642 ServerWindow* wm_root = FirstRoot(wm_tree());
608 ASSERT_TRUE(wm_root); 643 ASSERT_TRUE(wm_root);
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 client->tracker()->changes()->clear(); 1422 client->tracker()->changes()->clear();
1388 } 1423 }
1389 1424
1390 // Client should not have got any messages after shutdown. 1425 // Client should not have got any messages after shutdown.
1391 EXPECT_TRUE(client->tracker()->changes()->empty()); 1426 EXPECT_TRUE(client->tracker()->changes()->empty());
1392 } 1427 }
1393 1428
1394 } // namespace test 1429 } // namespace test
1395 } // namespace ws 1430 } // namespace ws
1396 } // namespace ui 1431 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/ws/window_server.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698