| 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 |