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

Unified Diff: trunk/src/ash/sticky_keys/sticky_keys_unittest.cc

Issue 341923006: Revert 278342 "Convert sticky keys to a chromeos::EventRewriter ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: trunk/src/ash/sticky_keys/sticky_keys_unittest.cc
===================================================================
--- trunk/src/ash/sticky_keys/sticky_keys_unittest.cc (revision 278418)
+++ trunk/src/ash/sticky_keys/sticky_keys_unittest.cc (working copy)
@@ -16,7 +16,8 @@
#include "base/memory/scoped_vector.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
-#include "ui/events/event_source.h"
+#include "ui/events/event_handler.h"
+#include "ui/events/event_processor.h"
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/events/x/device_data_manager.h"
@@ -29,7 +30,107 @@
} // namespace
-class StickyKeysTest : public test::AshTestBase {
+// Keeps a buffer of handled events.
+class EventBuffer : public ui::EventHandler {
+ public:
+ EventBuffer() {}
+ virtual ~EventBuffer() {}
+
+ void PopEvents(ScopedVector<ui::Event>* events) {
+ events->clear();
+ events->swap(events_);
+ }
+
+ private:
+ // ui::EventHandler overrides:
+ virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
+ events_.push_back(new ui::KeyEvent(*event));
+ }
+
+ virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
+ if (event->IsMouseWheelEvent()) {
+ events_.push_back(
+ new ui::MouseWheelEvent(*static_cast<ui::MouseWheelEvent*>(event)));
+ } else {
+ events_.push_back(new ui::MouseEvent(*event));
+ }
+ }
+
+ ScopedVector<ui::Event> events_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventBuffer);
+};
+
+// A testable and StickyKeysHandler.
+class MockStickyKeysHandlerDelegate :
+ public StickyKeysHandler::StickyKeysHandlerDelegate {
+ public:
+ class Delegate {
+ public:
+ virtual aura::Window* GetExpectedTarget() = 0;
+ virtual void OnShortcutPressed() = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ MockStickyKeysHandlerDelegate(Delegate* delegate) : delegate_(delegate) {}
+
+ virtual ~MockStickyKeysHandlerDelegate() {}
+
+ // StickyKeysHandler override.
+ virtual void DispatchKeyEvent(ui::KeyEvent* event,
+ aura::Window* target) OVERRIDE {
+ ASSERT_EQ(delegate_->GetExpectedTarget(), target);
+
+ // Detect a special shortcut when it is dispatched. This shortcut will
+ // not be hit in the LOCKED state as this case does not involve the
+ // delegate.
+ if (event->type() == ui::ET_KEY_PRESSED &&
+ event->key_code() == ui::VKEY_J &&
+ event->flags() | ui::EF_CONTROL_DOWN) {
+ delegate_->OnShortcutPressed();
+ }
+
+ events_.push_back(new ui::KeyEvent(*event));
+ }
+
+ virtual void DispatchMouseEvent(ui::MouseEvent* event,
+ aura::Window* target) OVERRIDE {
+ ASSERT_EQ(delegate_->GetExpectedTarget(), target);
+ events_.push_back(
+ new ui::MouseEvent(*event, target, target->GetRootWindow()));
+ }
+
+ virtual void DispatchScrollEvent(ui::ScrollEvent* event,
+ aura::Window* target) OVERRIDE {
+ events_.push_back(new ui::ScrollEvent(event->native_event()));
+ }
+
+ // Returns the count of dispatched events.
+ size_t GetEventCount() const {
+ return events_.size();
+ }
+
+ // Returns the |index|-th dispatched event.
+ const ui::Event* GetEvent(size_t index) const {
+ return events_[index];
+ }
+
+ // Clears all previously dispatched events.
+ void ClearEvents() {
+ events_.clear();
+ }
+
+ private:
+ ScopedVector<ui::Event> events_;
+ Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockStickyKeysHandlerDelegate);
+};
+
+class StickyKeysTest : public test::AshTestBase,
+ public MockStickyKeysHandlerDelegate::Delegate {
protected:
StickyKeysTest()
: target_(NULL),
@@ -50,35 +151,47 @@
test::AshTestBase::TearDown();
}
- virtual void OnShortcutPressed() {
+ // Overridden from MockStickyKeysHandlerDelegate::Delegate:
+ virtual aura::Window* GetExpectedTarget() OVERRIDE {
+ return target_ ? target_ : root_window_;
+ }
+
+ virtual void OnShortcutPressed() OVERRIDE {
if (target_) {
delete target_;
target_ = NULL;
}
}
- ui::KeyEvent* GenerateKey(ui::EventType type, ui::KeyboardCode code) {
- scoped_xevent_.InitKeyEvent(type, code, 0);
- ui::KeyEvent* event = new ui::KeyEvent(scoped_xevent_, false);
+ ui::KeyEvent* GenerateKey(bool is_key_press, ui::KeyboardCode code) {
+ scoped_xevent_.InitKeyEvent(
+ is_key_press ? ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED,
+ code,
+ 0);
+ ui::KeyEvent* event = new ui::KeyEvent(scoped_xevent_, false);
+ ui::Event::DispatcherApi dispatcher(event);
+ dispatcher.set_target(target_);
return event;
}
// Creates a mouse event backed by a native XInput2 generic button event.
// This is the standard native event on Chromebooks.
- ui::MouseEvent* GenerateMouseEvent(ui::EventType type) {
- return GenerateMouseEventAt(type, gfx::Point());
+ ui::MouseEvent* GenerateMouseEvent(bool is_button_press) {
+ return GenerateMouseEventAt(is_button_press, gfx::Point());
}
// Creates a mouse event backed by a native XInput2 generic button event.
// The |location| should be in physical pixels.
- ui::MouseEvent* GenerateMouseEventAt(ui::EventType type,
+ ui::MouseEvent* GenerateMouseEventAt(bool is_button_press,
const gfx::Point& location) {
scoped_xevent_.InitGenericButtonEvent(
kTouchPadDeviceId,
- type,
+ is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
location,
0);
ui::MouseEvent* event = new ui::MouseEvent(scoped_xevent_);
+ ui::Event::DispatcherApi dispatcher(event);
+ dispatcher.set_target(target_);
return event;
}
@@ -121,9 +234,14 @@
}
// Creates a synthesized KeyEvent that is not backed by a native event.
- ui::KeyEvent* GenerateSynthesizedKeyEvent(ui::EventType type,
- ui::KeyboardCode code) {
- return new ui::KeyEvent(type, code, 0, true);
+ ui::KeyEvent* GenerateSynthesizedKeyEvent(
+ bool is_key_press, ui::KeyboardCode code) {
+ ui::KeyEvent* event = new ui::KeyEvent(
+ is_key_press ? ui::ET_KEY_PRESSED : ui::ET_MOUSE_RELEASED,
+ code, 0, true);
+ ui::Event::DispatcherApi dispatcher(event);
+ dispatcher.set_target(target_);
+ return event;
}
// Creates a synthesized MouseEvent that is not backed by a native event.
@@ -141,9 +259,11 @@
// Creates a synthesized mouse press or release event.
ui::MouseEvent* GenerateSynthesizedMouseClickEvent(
- ui::EventType type,
+ bool is_button_press,
const gfx::Point& location) {
- return GenerateSynthesizedMouseEventAt(type, location);
+ return GenerateSynthesizedMouseEventAt(
+ is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED,
+ location);
}
// Creates a synthesized ET_MOUSE_MOVED event.
@@ -164,30 +284,24 @@
void SendActivateStickyKeyPattern(StickyKeysHandler* handler,
ui::KeyboardCode key_code) {
- bool released = false;
- int down_flags = 0;
scoped_ptr<ui::KeyEvent> ev;
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, key_code));
- handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, key_code));
- handler->HandleKeyEvent(*ev.get(), key_code, &down_flags, &released);
+ ev.reset(GenerateKey(true, key_code));
+ handler->HandleKeyEvent(ev.get());
+ ev.reset(GenerateKey(false, key_code));
+ handler->HandleKeyEvent(ev.get());
}
- bool HandleKeyEvent(const ui::KeyEvent& key_event,
- StickyKeysHandler* handler,
- int* down,
- bool* up) {
- return handler->HandleKeyEvent(key_event, key_event.key_code(), down, up);
+ void SendActivateStickyKeyPattern(ui::EventProcessor* dispatcher,
+ ui::KeyboardCode key_code) {
+ scoped_ptr<ui::KeyEvent> ev;
+ ev.reset(GenerateKey(true, key_code));
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
+ CHECK(!details.dispatcher_destroyed);
+ ev.reset(GenerateKey(false, key_code));
+ details = dispatcher->OnEventFromSource(ev.get());
+ CHECK(!details.dispatcher_destroyed);
}
- int HandleKeyEventForDownFlags(const ui::KeyEvent& key_event,
- StickyKeysHandler* handler) {
- bool released = false;
- int down = 0;
- handler->HandleKeyEvent(key_event, key_event.key_code(), &down, &released);
- return down;
- }
-
aura::Window* target() { return target_; }
private:
@@ -204,7 +318,9 @@
TEST_F(StickyKeysTest, BasicOneshotScenarioTest) {
scoped_ptr<ui::KeyEvent> ev;
- StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
@@ -212,42 +328,42 @@
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A));
- bool released = false;
- int mod_down_flags = 0;
- HandleKeyEvent(*ev.get(), &sticky_key, &mod_down_flags, &released);
+ ev.reset(GenerateKey(true, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
+
// Next keyboard event is shift modified.
- EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN);
- // Modifier release notification happens.
- EXPECT_TRUE(released);
+ EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A));
- released = false;
- mod_down_flags = 0;
- HandleKeyEvent(*ev.get(), &sticky_key, &mod_down_flags, &released);
+ ev.reset(GenerateKey(false, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- // Making sure Shift up keyboard event is available.
- scoped_ptr<ui::Event> up_event;
- ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event));
- EXPECT_TRUE(up_event.get());
- EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type());
+ // Making sure Shift up keyboard event is dispatched.
+ ASSERT_EQ(2U, mock_delegate->GetEventCount());
+ EXPECT_EQ(ui::ET_KEY_PRESSED, mock_delegate->GetEvent(0)->type());
+ EXPECT_EQ(ui::VKEY_A,
+ static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(0))
+ ->key_code());
+ EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
EXPECT_EQ(ui::VKEY_SHIFT,
- static_cast<const ui::KeyEvent*>(up_event.get())->key_code());
+ static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
+ ->key_code());
// Enabled state is one shot, so next key event should not be shift modified.
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_FALSE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(true, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_FALSE(ev->flags() & ui::EF_SHIFT_DOWN);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_FALSE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(false, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_FALSE(ev->flags() & ui::EF_SHIFT_DOWN);
}
TEST_F(StickyKeysTest, BasicLockedScenarioTest) {
scoped_ptr<ui::KeyEvent> ev;
- StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
@@ -260,24 +376,24 @@
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
// All keyboard events including keyUp become shift modified.
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_A));
- int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(true, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_A));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(false, ui::VKEY_A));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
// Locked state keeps after normal keyboard event.
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_B));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(true, ui::VKEY_B));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_B));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_SHIFT_DOWN);
+ ev.reset(GenerateKey(false, ui::VKEY_B));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_SHIFT_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
@@ -288,163 +404,146 @@
TEST_F(StickyKeysTest, NonTargetModifierTest) {
scoped_ptr<ui::KeyEvent> ev;
- StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_SHIFT_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Non target modifier key does not affect internal state
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU));
- int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(true, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(false, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
// Non target modifier key does not affect internal state
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(true, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(false, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_SHIFT);
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
// Non target modifier key does not affect internal state
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_MENU));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(true, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_MENU));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(false, ui::VKEY_MENU));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
}
TEST_F(StickyKeysTest, NormalShortcutTest) {
// Sticky keys should not be enabled if we perform a normal shortcut.
scoped_ptr<ui::KeyEvent> ev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Perform ctrl+n shortcut.
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
- int mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_N));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
+ ev.reset(GenerateKey(true, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(ev.get());
+ ev.reset(GenerateKey(true, ui::VKEY_N));
+ sticky_key.HandleKeyEvent(ev.get());
+ ev.reset(GenerateKey(false, ui::VKEY_N));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
// Sticky keys should not be enabled afterwards.
+ ev.reset(GenerateKey(false, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
-
- // Perform ctrl+n shortcut, releasing ctrl first.
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- ev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
- ev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_N));
- mod_down_flags = HandleKeyEventForDownFlags(*ev.get(), &sticky_key);
-
- // Sticky keys should not be enabled afterwards.
- EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
}
TEST_F(StickyKeysTest, NormalModifiedClickTest) {
scoped_ptr<ui::KeyEvent> kev;
scoped_ptr<ui::MouseEvent> mev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Perform ctrl+click.
- kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
- int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
- mev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED));
- bool released = false;
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
- mev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED));
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
+ kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(kev.get());
+ mev.reset(GenerateMouseEvent(true));
+ sticky_key.HandleMouseEvent(mev.get());
+ mev.reset(GenerateMouseEvent(false));
+ sticky_key.HandleMouseEvent(mev.get());
// Sticky keys should not be enabled afterwards.
- kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
+ kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(kev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
}
TEST_F(StickyKeysTest, MouseMovedModifierTest) {
scoped_ptr<ui::KeyEvent> kev;
scoped_ptr<ui::MouseEvent> mev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Press ctrl and handle mouse move events.
- kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
- int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
+ kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(kev.get());
mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(0, 0)));
- bool released = false;
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
+ sticky_key.HandleMouseEvent(mev.get());
mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(100, 100)));
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
+ sticky_key.HandleMouseEvent(mev.get());
// Sticky keys should be enabled afterwards.
- kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
+ kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(kev.get());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
}
TEST_F(StickyKeysTest, NormalModifiedScrollTest) {
scoped_ptr<ui::KeyEvent> kev;
scoped_ptr<ui::ScrollEvent> sev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Perform ctrl+scroll.
- kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_CONTROL));
- int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
+ kev.reset(GenerateKey(true, ui::VKEY_CONTROL));
sev.reset(GenerateFlingScrollEvent(0, true));
- bool released = false;
- sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(sev.get());
sev.reset(GenerateScrollEvent(10));
- sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(sev.get());
sev.reset(GenerateFlingScrollEvent(10, false));
- sticky_key.HandleScrollEvent(*sev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(sev.get());
// Sticky keys should not be enabled afterwards.
- kev.reset(GenerateKey(ui::ET_KEY_RELEASED, ui::VKEY_CONTROL));
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
+ kev.reset(GenerateKey(false, ui::VKEY_CONTROL));
+ sticky_key.HandleKeyEvent(kev.get());
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- EXPECT_EQ(ui::EF_NONE, mod_down_flags);
}
TEST_F(StickyKeysTest, MouseEventOneshot) {
scoped_ptr<ui::MouseEvent> ev;
scoped_ptr<ui::KeyEvent> kev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
@@ -452,47 +551,40 @@
// We should still be in the ENABLED state until we get the mouse
// release event.
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED));
- bool released = false;
- int mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(true));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(false));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Making sure modifier key release event is dispatched in the right order.
- EXPECT_TRUE(released);
- scoped_ptr<ui::Event> up_event;
- ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event));
- EXPECT_TRUE(up_event.get());
- EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type());
+ ASSERT_EQ(2u, mock_delegate->GetEventCount());
+ EXPECT_EQ(ui::ET_MOUSE_RELEASED, mock_delegate->GetEvent(0)->type());
+ EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
EXPECT_EQ(ui::VKEY_CONTROL,
- static_cast<const ui::KeyEvent*>(up_event.get())->key_code());
+ static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
+ ->key_code());
// Enabled state is one shot, so next click should not be control modified.
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(true));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(false));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
}
TEST_F(StickyKeysTest, MouseEventLocked) {
scoped_ptr<ui::MouseEvent> ev;
scoped_ptr<ui::KeyEvent> kev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
@@ -504,44 +596,35 @@
// Mouse events should not disable locked mode.
for (int i = 0; i < 3; ++i) {
- bool released = false;
- int mod_down_flags = 0;
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_PRESSED));
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
- ev.reset(GenerateMouseEvent(ui::ET_MOUSE_RELEASED));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(true));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
+ ev.reset(GenerateMouseEvent(false));
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
}
// Test with mouse wheel.
for (int i = 0; i < 3; ++i) {
- bool released = false;
- int mod_down_flags = 0;
ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
+ sticky_key.HandleMouseEvent(ev.get());
ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
}
// Test mixed case with mouse events and key events.
ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
- bool released = false;
- int mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
- kev.reset(GenerateKey(ui::ET_KEY_PRESSED, ui::VKEY_N));
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleMouseEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
+ kev.reset(GenerateKey(true, ui::VKEY_N));
+ sticky_key.HandleKeyEvent(kev.get());
+ EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
+ kev.reset(GenerateKey(false, ui::VKEY_N));
+ sticky_key.HandleKeyEvent(kev.get());
+ EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
}
@@ -549,10 +632,14 @@
TEST_F(StickyKeysTest, ScrollEventOneshot) {
scoped_ptr<ui::ScrollEvent> ev;
scoped_ptr<ui::KeyEvent> kev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
int scroll_deltas[] = {-10, 10};
for (int i = 0; i < 2; ++i) {
+ mock_delegate->ClearEvents();
+
// Enable sticky keys.
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
@@ -561,44 +648,42 @@
// Test a scroll sequence. Sticky keys should only be disabled at the end
// of the scroll sequence. Fling cancel event starts the scroll sequence.
ev.reset(GenerateFlingScrollEvent(0, true));
- bool released = false;
- int mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
// Scrolls should all be modified but not disable sticky keys.
for (int j = 0; j < 3; ++j) {
ev.reset(GenerateScrollEvent(scroll_deltas[i]));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
}
// Fling start event ends scroll sequence.
ev.reset(GenerateFlingScrollEvent(scroll_deltas[i], false));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- scoped_ptr<ui::Event> up_event;
- EXPECT_TRUE(released);
- ASSERT_EQ(0, sticky_key.GetModifierUpEvent(&up_event));
- EXPECT_TRUE(up_event.get());
- EXPECT_EQ(ui::ET_KEY_RELEASED, up_event->type());
+ ASSERT_EQ(2U, mock_delegate->GetEventCount());
+ EXPECT_EQ(ui::ET_SCROLL_FLING_START, mock_delegate->GetEvent(0)->type());
+ EXPECT_FLOAT_EQ(scroll_deltas[i],
+ static_cast<const ui::ScrollEvent*>(
+ mock_delegate->GetEvent(0))->y_offset());
+ EXPECT_EQ(ui::ET_KEY_RELEASED, mock_delegate->GetEvent(1)->type());
EXPECT_EQ(ui::VKEY_CONTROL,
- static_cast<const ui::KeyEvent*>(up_event.get())->key_code());
+ static_cast<const ui::KeyEvent*>(mock_delegate->GetEvent(1))
+ ->key_code());
}
}
TEST_F(StickyKeysTest, ScrollDirectionChanged) {
scoped_ptr<ui::ScrollEvent> ev;
scoped_ptr<ui::KeyEvent> kev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
// Test direction change with both boundary value and negative value.
const int direction_change_values[2] = {0, -10};
@@ -608,26 +693,21 @@
// Fling cancel starts scroll sequence.
ev.reset(GenerateFlingScrollEvent(0, true));
- bool released = false;
- int mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(ev.get());
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
// Test that changing directions in a scroll sequence will
// return sticky keys to DISABLED state.
for (int j = 0; j < 3; ++j) {
ev.reset(GenerateScrollEvent(10));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
}
ev.reset(GenerateScrollEvent(direction_change_values[i]));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_FALSE(ev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
}
}
@@ -635,7 +715,9 @@
TEST_F(StickyKeysTest, ScrollEventLocked) {
scoped_ptr<ui::ScrollEvent> ev;
scoped_ptr<ui::KeyEvent> kev;
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
// Lock sticky keys.
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
@@ -646,45 +728,63 @@
for (int i = 0; i < 5; ++i) {
// Fling cancel starts scroll sequence.
ev.reset(GenerateFlingScrollEvent(0, true));
- bool released = false;
- int mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(ev.get());
ev.reset(GenerateScrollEvent(10));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
ev.reset(GenerateScrollEvent(-10));
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ sticky_key.HandleScrollEvent(ev.get());
+ EXPECT_TRUE(ev->flags() & ui::EF_CONTROL_DOWN);
// Fling start ends scroll sequence.
ev.reset(GenerateFlingScrollEvent(-10, false));
- sticky_key.HandleScrollEvent(*ev.get(), &mod_down_flags, &released);
+ sticky_key.HandleScrollEvent(ev.get());
}
EXPECT_EQ(STICKY_KEY_STATE_LOCKED, sticky_key.current_state());
}
+TEST_F(StickyKeysTest, EventTargetDestroyed) {
+ scoped_ptr<ui::KeyEvent> ev;
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
+
+ target()->Focus();
+
+ // Go into ENABLED state.
+ EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
+ SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
+ EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
+
+ // CTRL+J is a special shortcut that will destroy the event target.
+ ev.reset(GenerateKey(true, ui::VKEY_J));
+ sticky_key.HandleKeyEvent(ev.get());
+ EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
+ EXPECT_FALSE(target());
+}
+
TEST_F(StickyKeysTest, SynthesizedEvents) {
// Non-native, internally generated events should be properly handled
// by sticky keys.
- StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN);
+ MockStickyKeysHandlerDelegate* mock_delegate =
+ new MockStickyKeysHandlerDelegate(this);
+ StickyKeysHandler sticky_key(ui::EF_CONTROL_DOWN, mock_delegate);
// Test non-native key events.
scoped_ptr<ui::KeyEvent> kev;
SendActivateStickyKeyPattern(&sticky_key, ui::VKEY_CONTROL);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- kev.reset(GenerateSynthesizedKeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_K));
- int mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ kev.reset(GenerateSynthesizedKeyEvent(true, ui::VKEY_K));
+ sticky_key.HandleKeyEvent(kev.get());
+ EXPECT_TRUE(kev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
- kev.reset(GenerateSynthesizedKeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_K));
- mod_down_flags = HandleKeyEventForDownFlags(*kev.get(), &sticky_key);
- EXPECT_FALSE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ kev.reset(GenerateSynthesizedKeyEvent(false, ui::VKEY_K));
+ sticky_key.HandleKeyEvent(kev.get());
+ EXPECT_FALSE(kev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
// Test non-native mouse events.
@@ -692,21 +792,216 @@
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
scoped_ptr<ui::MouseEvent> mev;
- mev.reset(GenerateSynthesizedMouseClickEvent(ui::ET_MOUSE_PRESSED,
- gfx::Point(0, 0)));
- bool released = false;
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
+ mev.reset(GenerateSynthesizedMouseClickEvent(true, gfx::Point(0, 0)));
+ sticky_key.HandleMouseEvent(mev.get());
+ EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state());
- mev.reset(GenerateSynthesizedMouseClickEvent(ui::ET_MOUSE_RELEASED,
- gfx::Point(0, 0)));
- released = false;
- mod_down_flags = 0;
- sticky_key.HandleMouseEvent(*mev.get(), &mod_down_flags, &released);
- EXPECT_TRUE(mod_down_flags & ui::EF_CONTROL_DOWN);
- EXPECT_TRUE(released);
+ mev.reset(GenerateSynthesizedMouseClickEvent(false, gfx::Point(0, 0)));
+ sticky_key.HandleMouseEvent(mev.get());
+ EXPECT_TRUE(mev->flags() & ui::EF_CONTROL_DOWN);
EXPECT_EQ(STICKY_KEY_STATE_DISABLED, sticky_key.current_state());
}
+TEST_F(StickyKeysTest, KeyEventDispatchImpl) {
+ // Test the actual key event dispatch implementation.
+ EventBuffer buffer;
+ ScopedVector<ui::Event> events;
+ ui::EventProcessor* dispatcher =
+ Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
+ Shell::GetInstance()->AddPreTargetHandler(&buffer);
+ Shell::GetInstance()->sticky_keys_controller()->Enable(true);
+
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ scoped_ptr<ui::KeyEvent> ev;
+ buffer.PopEvents(&events);
+
+ // Test key press event is correctly modified and modifier release
+ // event is sent.
+ ev.reset(GenerateKey(true, ui::VKEY_C));
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
+ EXPECT_EQ(ui::VKEY_C, static_cast<ui::KeyEvent*>(events[0])->key_code());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ // Test key release event is not modified.
+ ev.reset(GenerateKey(false, ui::VKEY_C));
+ details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(1u, events.size());
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[0]->type());
+ EXPECT_EQ(ui::VKEY_C,
+ static_cast<ui::KeyEvent*>(events[0])->key_code());
+ EXPECT_FALSE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+
+ // Test that synthesized key events are dispatched correctly.
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+ scoped_ptr<ui::KeyEvent> kev;
+ kev.reset(GenerateSynthesizedKeyEvent(true, ui::VKEY_K));
+ details = dispatcher->OnEventFromSource(kev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_EQ(ui::ET_KEY_PRESSED, events[0]->type());
+ EXPECT_EQ(ui::VKEY_K, static_cast<ui::KeyEvent*>(events[0])->key_code());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ Shell::GetInstance()->RemovePreTargetHandler(&buffer);
+}
+
+class StickyKeysMouseDispatchTest
+ : public StickyKeysTest,
+ public ::testing::WithParamInterface<int> {
+};
+
+TEST_P(StickyKeysMouseDispatchTest, MouseEventDispatchImpl) {
+ int scale_factor = GetParam();
+ std::ostringstream display_specs;
+ display_specs << "1280x1024*" << scale_factor;
+ UpdateDisplay(display_specs.str());
+
+ EventBuffer buffer;
+ ScopedVector<ui::Event> events;
+ ui::EventProcessor* dispatcher =
+ Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
+ Shell::GetInstance()->AddPreTargetHandler(&buffer);
+ Shell::GetInstance()->sticky_keys_controller()->Enable(true);
+
+ scoped_ptr<ui::MouseEvent> ev;
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+
+ // Test mouse press event is correctly modified and has correct DIP location.
+ gfx::Point physical_location(400, 400);
+ gfx::Point dip_location(physical_location.x() / scale_factor,
+ physical_location.y() / scale_factor);
+ ev.reset(GenerateMouseEventAt(true, physical_location));
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
+ buffer.PopEvents(&events);
+ EXPECT_EQ(1u, events.size());
+ EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0]->type());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(dip_location.ToString(),
+ static_cast<ui::MouseEvent*>(events[0])->location().ToString());
+
+ // Test mouse release event is correctly modified and modifier release
+ // event is sent. The mouse event should have the correct DIP location.
+ ev.reset(GenerateMouseEventAt(false, physical_location));
+ details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(dip_location.ToString(),
+ static_cast<ui::MouseEvent*>(events[0])->location().ToString());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ // Test synthesized mouse events are dispatched correctly.
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+ ev.reset(GenerateSynthesizedMouseClickEvent(false, physical_location));
+ details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0]->type());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(dip_location.ToString(),
+ static_cast<ui::MouseEvent*>(events[0])->location().ToString());
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ Shell::GetInstance()->RemovePreTargetHandler(&buffer);
+}
+
+TEST_P(StickyKeysMouseDispatchTest, MouseWheelEventDispatchImpl) {
+ int scale_factor = GetParam();
+ std::ostringstream display_specs;
+ display_specs << "1280x1024*" << scale_factor;
+ UpdateDisplay(display_specs.str());
+
+ // Test the actual mouse wheel event dispatch implementation.
+ EventBuffer buffer;
+ ScopedVector<ui::Event> events;
+ ui::EventProcessor* dispatcher =
+ Shell::GetPrimaryRootWindow()->GetHost()->event_processor();
+ Shell::GetInstance()->AddPreTargetHandler(&buffer);
+ Shell::GetInstance()->sticky_keys_controller()->Enable(true);
+
+ scoped_ptr<ui::MouseWheelEvent> ev;
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+
+ // Test positive mouse wheel event is correctly modified and modifier release
+ // event is sent.
+ ev.reset(GenerateMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_TRUE(events[0]->IsMouseWheelEvent());
+ EXPECT_EQ(ui::MouseWheelEvent::kWheelDelta / scale_factor,
+ static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ // Test negative mouse wheel event is correctly modified and modifier release
+ // event is sent.
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+
+ ev.reset(GenerateMouseWheelEvent(-ui::MouseWheelEvent::kWheelDelta));
+ details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_TRUE(events[0]->IsMouseWheelEvent());
+ EXPECT_EQ(-ui::MouseWheelEvent::kWheelDelta / scale_factor,
+ static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ // Test synthesized mouse wheel events are dispatched correctly.
+ SendActivateStickyKeyPattern(dispatcher, ui::VKEY_CONTROL);
+ buffer.PopEvents(&events);
+ ev.reset(
+ GenerateSynthesizedMouseWheelEvent(ui::MouseWheelEvent::kWheelDelta));
+ details = dispatcher->OnEventFromSource(ev.get());
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ buffer.PopEvents(&events);
+ EXPECT_EQ(2u, events.size());
+ EXPECT_TRUE(events[0]->IsMouseWheelEvent());
+ EXPECT_EQ(ui::MouseWheelEvent::kWheelDelta / scale_factor,
+ static_cast<ui::MouseWheelEvent*>(events[0])->y_offset());
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_TRUE(events[0]->flags() & ui::EF_CONTROL_DOWN);
+ EXPECT_EQ(ui::ET_KEY_RELEASED, events[1]->type());
+ EXPECT_EQ(ui::VKEY_CONTROL,
+ static_cast<ui::KeyEvent*>(events[1])->key_code());
+
+ Shell::GetInstance()->RemovePreTargetHandler(&buffer);
+}
+
+INSTANTIATE_TEST_CASE_P(DPIScaleFactors,
+ StickyKeysMouseDispatchTest,
+ ::testing::Values(1, 2));
+
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698