OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ash/wm/sticky_keys.h" | 5 #include "ash/wm/sticky_keys.h" |
6 | 6 |
7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
8 #undef None | 8 #undef None |
9 #undef Bool | 9 #undef Bool |
10 #undef RootWindow | 10 #undef RootWindow |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 XEvent* xev = new XEvent(); | 194 XEvent* xev = new XEvent(); |
195 ui::InitXMouseWheelEventForTesting(wheel_delta, 0, xev); | 195 ui::InitXMouseWheelEventForTesting(wheel_delta, 0, xev); |
196 xevs_.push_back(xev); | 196 xevs_.push_back(xev); |
197 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(xev); | 197 ui::MouseWheelEvent* event = new ui::MouseWheelEvent(xev); |
198 ui::Event::DispatcherApi dispatcher(event); | 198 ui::Event::DispatcherApi dispatcher(event); |
199 dispatcher.set_target(target_); | 199 dispatcher.set_target(target_); |
200 return event; | 200 return event; |
201 } | 201 } |
202 | 202 |
203 ui::ScrollEvent* GenerateScrollEvent(int scroll_delta) { | 203 ui::ScrollEvent* GenerateScrollEvent(int scroll_delta) { |
204 EXPECT_FALSE(scroll_delta == 0); | |
205 XEvent* xev = ui::CreateScrollEventForTest( | 204 XEvent* xev = ui::CreateScrollEventForTest( |
206 kScrollDeviceId, // deviceid | 205 kScrollDeviceId, // deviceid |
207 0, // x_offset | 206 0, // x_offset |
208 scroll_delta, // y_offset | 207 scroll_delta, // y_offset |
209 0, // x_offset_ordinal | 208 0, // x_offset_ordinal |
210 scroll_delta, // y_offset_ordinal | 209 scroll_delta, // y_offset_ordinal |
211 2); // finger_count | 210 2); // finger_count |
212 xi2_evs_.push_back(new ui::ScopedXI2Event(xev)); | 211 xi2_evs_.push_back(new ui::ScopedXI2Event(xev)); |
213 | 212 |
214 ui::ScrollEvent* event = new ui::ScrollEvent(xev); | 213 ui::ScrollEvent* event = new ui::ScrollEvent(xev); |
215 ui::Event::DispatcherApi dispatcher(event); | 214 ui::Event::DispatcherApi dispatcher(event); |
216 dispatcher.set_target(target_); | 215 dispatcher.set_target(target_); |
217 return event; | 216 return event; |
218 } | 217 } |
219 | 218 |
| 219 ui::ScrollEvent* GenerateScrollFlingEvent(int fling_delta, |
| 220 bool is_cancel) { |
| 221 XEvent* xev = ui::CreateFlingEventForTest( |
| 222 kScrollDeviceId, // deviceid |
| 223 0, // x_velocity |
| 224 fling_delta, // y_velocity |
| 225 0, // x_velocity_ordinal |
| 226 fling_delta, // y_velocity_ordinal |
| 227 is_cancel); // is_cancel |
| 228 ui::ScrollEvent* event = new ui::ScrollEvent(xev); |
| 229 ui::Event::DispatcherApi dispatcher(event); |
| 230 dispatcher.set_target(target_); |
| 231 |
| 232 return event; |
| 233 } |
| 234 |
220 // Creates a synthesized KeyEvent that is not backed by a native event. | 235 // Creates a synthesized KeyEvent that is not backed by a native event. |
221 ui::KeyEvent* GenerateSynthesizedKeyEvent( | 236 ui::KeyEvent* GenerateSynthesizedKeyEvent( |
222 bool is_key_press, ui::KeyboardCode code) { | 237 bool is_key_press, ui::KeyboardCode code) { |
223 ui::KeyEvent* event = new ui::KeyEvent( | 238 ui::KeyEvent* event = new ui::KeyEvent( |
224 is_key_press ? ui::ET_KEY_PRESSED : ui::ET_MOUSE_RELEASED, | 239 is_key_press ? ui::ET_KEY_PRESSED : ui::ET_MOUSE_RELEASED, |
225 code, 0, true); | 240 code, 0, true); |
226 ui::Event::DispatcherApi dispatcher(event); | 241 ui::Event::DispatcherApi dispatcher(event); |
227 dispatcher.set_target(target_); | 242 dispatcher.set_target(target_); |
228 return event; | 243 return event; |
229 } | 244 } |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 kev.reset(GenerateKey(true, ui::VKEY_N)); | 526 kev.reset(GenerateKey(true, ui::VKEY_N)); |
512 sticky_key.HandleKeyEvent(kev.get()); | 527 sticky_key.HandleKeyEvent(kev.get()); |
513 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); | 528 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); |
514 kev.reset(GenerateKey(false, ui::VKEY_N)); | 529 kev.reset(GenerateKey(false, ui::VKEY_N)); |
515 sticky_key.HandleKeyEvent(kev.get()); | 530 sticky_key.HandleKeyEvent(kev.get()); |
516 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); | 531 EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN); |
517 | 532 |
518 EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); | 533 EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); |
519 } | 534 } |
520 | 535 |
521 TEST_F(StickyKeysTest, ScrollEvents) { | 536 TEST_F(StickyKeysTest, ScrollEventOneshot) { |
522 ui::SetUpScrollDeviceForTest(kScrollDeviceId); | 537 ui::SetUpScrollDeviceForTest(kScrollDeviceId); |
523 // Australlian scrolling is enabled by default for some reason. | 538 // Disable Australlian scrolling. |
524 ui::DeviceDataManager::GetInstance()->set_natural_scroll_enabled(true); | 539 ui::DeviceDataManager::GetInstance()->set_natural_scroll_enabled(true); |
525 | 540 |
526 scoped_ptr<ui::ScrollEvent> ev; | 541 scoped_ptr<ui::ScrollEvent> ev; |
527 scoped_ptr<ui::KeyEvent> kev; | 542 scoped_ptr<ui::KeyEvent> kev; |
528 MockStickyKeysHandlerDelegate* mock_delegate = | 543 MockStickyKeysHandlerDelegate* mock_delegate = |
529 new MockStickyKeysHandlerDelegate(this); | 544 new MockStickyKeysHandlerDelegate(this); |
530 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); | 545 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); |
531 | 546 |
532 int scroll_deltas[] = {-10, 10}; | 547 int scroll_deltas[] = {-10, 10}; |
533 for (int i = 0; i < 2; ++i) { | 548 for (int i = 0; i < 2; ++i) { |
534 mock_delegate->ClearEvents(); | 549 mock_delegate->ClearEvents(); |
535 | 550 |
536 // Enable sticky keys. | 551 // Enable sticky keys. |
537 EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); | 552 EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); |
538 kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); | 553 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); |
539 sticky_key.HandleKeyEvent(kev.get()); | |
540 kev.reset(GenerateKey(false, ui::VKEY_CONTROL)); | |
541 sticky_key.HandleKeyEvent(kev.get()); | |
542 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); | 554 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
543 | 555 |
544 // Test scroll event is correctly modified. | 556 // Test a scroll sequence. Sticky keys should only be disabled at the end |
545 ev.reset(GenerateScrollEvent(scroll_deltas[i])); | 557 // of the scroll sequence. Fling cancel event starts the scroll sequence. |
| 558 ev.reset(GenerateScrollFlingEvent(0, true)); |
| 559 sticky_key.HandleScrollEvent(ev.get()); |
| 560 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
| 561 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
| 562 |
| 563 // Scrolls should all be modified but not disable sticky keys. |
| 564 for (int j = 0; j < 3; ++j) { |
| 565 ev.reset(GenerateScrollEvent(scroll_deltas[i])); |
| 566 sticky_key.HandleScrollEvent(ev.get()); |
| 567 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
| 568 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
| 569 } |
| 570 |
| 571 // Fling start event ends scroll sequence. |
| 572 ev.reset(GenerateScrollFlingEvent(scroll_deltas[i], false)); |
546 sticky_key.HandleScrollEvent(ev.get()); | 573 sticky_key.HandleScrollEvent(ev.get()); |
547 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); | 574 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
548 EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); | 575 EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); |
549 | 576 |
550 ASSERT_EQ(2U, mock_delegate->GetEventCount()); | 577 ASSERT_EQ(2U, mock_delegate->GetEventCount()); |
551 EXPECT_EQ(ui::ET_SCROLL, mock_delegate->GetEvent(0)->type()); | 578 EXPECT_EQ(ui::ET_SCROLL_FLING_START, mock_delegate->GetEvent(0)->type()); |
552 EXPECT_FLOAT_EQ(scroll_deltas[i], | 579 EXPECT_FLOAT_EQ(scroll_deltas[i], |
553 static_cast<const ui::ScrollEvent*>( | 580 static_cast<const ui::ScrollEvent*>( |
554 mock_delegate->GetEvent(0))->y_offset()); | 581 mock_delegate->GetEvent(0))->y_offset()); |
555 EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type()); | 582 EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type()); |
556 EXPECT_EQ(ui::VKEY_CONTROL, | 583 EXPECT_EQ(ui::VKEY_CONTROL, |
557 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1)) | 584 static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1)) |
558 ->key_code()); | 585 ->key_code()); |
559 } | 586 } |
| 587 } |
| 588 |
| 589 TEST_F(StickyKeysTest, ScrollDirectionChanged) { |
| 590 ui::SetUpScrollDeviceForTest(kScrollDeviceId); |
| 591 // Disable Australlian scrolling. |
| 592 ui::DeviceDataManager::GetInstance()->set_natural_scroll_enabled(true); |
| 593 |
| 594 scoped_ptr<ui::ScrollEvent> ev; |
| 595 scoped_ptr<ui::KeyEvent> kev; |
| 596 MockStickyKeysHandlerDelegate* mock_delegate = |
| 597 new MockStickyKeysHandlerDelegate(this); |
| 598 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); |
| 599 |
| 600 // Test direction change with both boundary value and negative value. |
| 601 const int direction_change_values[2] = {0, -10}; |
| 602 for (int i = 0; i < 2; ++i) { |
| 603 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); |
| 604 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
| 605 |
| 606 // Fling cancel starts scroll sequence. |
| 607 ev.reset(GenerateScrollFlingEvent(0, true)); |
| 608 sticky_key.HandleScrollEvent(ev.get()); |
| 609 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
| 610 |
| 611 // Test that changing directions in a scroll sequence will |
| 612 // return sticky keys to DISABLED state. |
| 613 for (int j = 0; j < 3; ++j) { |
| 614 ev.reset(GenerateScrollEvent(10)); |
| 615 sticky_key.HandleScrollEvent(ev.get()); |
| 616 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
| 617 EXPECT_EQ(StickyKeysHandler::ENABLED, sticky_key.current_state()); |
| 618 } |
| 619 |
| 620 ev.reset(GenerateScrollEvent(direction_change_values[i])); |
| 621 sticky_key.HandleScrollEvent(ev.get()); |
| 622 EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN); |
| 623 EXPECT_EQ(StickyKeysHandler::DISABLED, sticky_key.current_state()); |
| 624 } |
| 625 } |
| 626 |
| 627 TEST_F(StickyKeysTest, ScrollEventLocked) { |
| 628 ui::SetUpScrollDeviceForTest(kScrollDeviceId); |
| 629 // Disable Australlian scrolling. |
| 630 ui::DeviceDataManager::GetInstance()->set_natural_scroll_enabled(true); |
| 631 |
| 632 scoped_ptr<ui::ScrollEvent> ev; |
| 633 scoped_ptr<ui::KeyEvent> kev; |
| 634 MockStickyKeysHandlerDelegate* mock_delegate = |
| 635 new MockStickyKeysHandlerDelegate(this); |
| 636 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); |
560 | 637 |
561 // Lock sticky keys. | 638 // Lock sticky keys. |
562 for (int i = 0; i < 2; ++i) { | 639 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); |
563 kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); | 640 SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL); |
564 sticky_key.HandleKeyEvent(kev.get()); | 641 EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); |
565 kev.reset(GenerateKey(false, ui::VKEY_CONTROL)); | |
566 sticky_key.HandleKeyEvent(kev.get()); | |
567 } | |
568 | 642 |
569 // Test scroll events are correctly modified in locked state. | 643 // Test scroll events are correctly modified in locked state. |
570 for (int i = 0; i < 5; ++i) { | 644 for (int i = 0; i < 5; ++i) { |
| 645 // Fling cancel starts scroll sequence. |
| 646 ev.reset(GenerateScrollFlingEvent(0, true)); |
| 647 sticky_key.HandleScrollEvent(ev.get()); |
| 648 |
571 ev.reset(GenerateScrollEvent(10)); | 649 ev.reset(GenerateScrollEvent(10)); |
572 sticky_key.HandleScrollEvent(ev.get()); | 650 sticky_key.HandleScrollEvent(ev.get()); |
573 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); | 651 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
574 ev.reset(GenerateScrollEvent(-10)); | 652 ev.reset(GenerateScrollEvent(-10)); |
575 sticky_key.HandleScrollEvent(ev.get()); | 653 sticky_key.HandleScrollEvent(ev.get()); |
576 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); | 654 EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN); |
| 655 |
| 656 // Fling start ends scroll sequence. |
| 657 ev.reset(GenerateScrollFlingEvent(-10, false)); |
| 658 sticky_key.HandleScrollEvent(ev.get()); |
577 } | 659 } |
578 | 660 |
579 EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); | 661 EXPECT_EQ(StickyKeysHandler::LOCKED, sticky_key.current_state()); |
580 } | 662 } |
581 | 663 |
582 TEST_F(StickyKeysTest, EventTargetDestroyed) { | 664 TEST_F(StickyKeysTest, EventTargetDestroyed) { |
583 scoped_ptr<ui::KeyEvent> ev; | 665 scoped_ptr<ui::KeyEvent> ev; |
584 MockStickyKeysHandlerDelegate* mock_delegate = | 666 MockStickyKeysHandlerDelegate* mock_delegate = |
585 new MockStickyKeysHandlerDelegate(this); | 667 new MockStickyKeysHandlerDelegate(this); |
586 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); | 668 StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 static_cast<ui::MouseWheelEvent*>(events[0])->y_offset()); | 835 static_cast<ui::MouseWheelEvent*>(events[0])->y_offset()); |
754 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN); | 836 EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN); |
755 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type()); | 837 EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type()); |
756 EXPECT_EQ(ui::VKEY_CONTROL, | 838 EXPECT_EQ(ui::VKEY_CONTROL, |
757 static_cast<ui::KeyEvent*>(events[1])->key_code()); | 839 static_cast<ui::KeyEvent*>(events[1])->key_code()); |
758 | 840 |
759 Shell::GetInstance()->RemovePreTargetHandler(&buffer); | 841 Shell::GetInstance()->RemovePreTargetHandler(&buffer); |
760 } | 842 } |
761 | 843 |
762 } // namespace ash | 844 } // namespace ash |
OLD | NEW |