diff options
author | tengs@chromium.org <tengs@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-08 18:57:32 +0000 |
---|---|---|
committer | tengs@chromium.org <tengs@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-08 18:57:32 +0000 |
commit | 993a789835cc172b20f2114122b15a2697447930 (patch) | |
tree | fa88cb6227a073c5e002c535e5da1c019c6ca57e /ash/sticky_keys | |
parent | aadde5988b5b71abcf99d1c4d8fa77290165b801 (diff) | |
download | chromium_src-993a789835cc172b20f2114122b15a2697447930.zip chromium_src-993a789835cc172b20f2114122b15a2697447930.tar.gz chromium_src-993a789835cc172b20f2114122b15a2697447930.tar.bz2 |
Fix sticky keys crash when handling synthetic events without a native event.
BUG=358270
TEST=modified tests
Review URL: https://codereview.chromium.org/227113009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262465 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/sticky_keys')
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.cc | 12 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_controller.h | 9 | ||||
-rw-r--r-- | ash/sticky_keys/sticky_keys_unittest.cc | 95 |
3 files changed, 93 insertions, 23 deletions
diff --git a/ash/sticky_keys/sticky_keys_controller.cc b/ash/sticky_keys/sticky_keys_controller.cc index e5bb0af..45c1248 100644 --- a/ash/sticky_keys/sticky_keys_controller.cc +++ b/ash/sticky_keys/sticky_keys_controller.cc @@ -69,10 +69,18 @@ void StickyKeysHandlerDelegateImpl::DispatchMouseEvent(ui::MouseEvent* event, DCHECK(target); // We need to send a new, untransformed mouse event to the host. if (event->IsMouseWheelEvent()) { - ui::MouseWheelEvent new_event(event->native_event()); + aura::Window* source = static_cast<aura::Window*>(event->target()); + ui::MouseWheelEvent new_event(*static_cast<ui::MouseWheelEvent*>(event), + source, + source->GetRootWindow()); + // Transform the location back to host coordinates before dispatching. + new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); DispatchEvent(&new_event, target); } else { - ui::MouseEvent new_event(event->native_event()); + aura::Window* source = static_cast<aura::Window*>(event->target()); + ui::MouseEvent new_event(*event, source, source->GetRootWindow()); + // Transform the location back to host coordinates before dispatching. + new_event.UpdateForRootTransform(source->GetHost()->GetRootTransform()); DispatchEvent(&new_event, target); } } diff --git a/ash/sticky_keys/sticky_keys_controller.h b/ash/sticky_keys/sticky_keys_controller.h index 792f2c5..c9c1580 100644 --- a/ash/sticky_keys/sticky_keys_controller.h +++ b/ash/sticky_keys/sticky_keys_controller.h @@ -147,15 +147,18 @@ class ASH_EXPORT StickyKeysHandler { StickyKeysHandlerDelegate(); virtual ~StickyKeysHandlerDelegate(); - // Dispatches keyboard event synchronously. + // Dispatches keyboard event synchronously. |event| is an event that has + // been previously dispatched. virtual void DispatchKeyEvent(ui::KeyEvent* event, aura::Window* target) = 0; - // Dispatches mouse event synchronously. + // Dispatches mouse event synchronously. |event| is an event that has + // been previously dispatched. virtual void DispatchMouseEvent(ui::MouseEvent* event, aura::Window* target) = 0; - // Dispatches scroll event synchronously. + // Dispatches scroll event synchronously. |event| is an event that has + // been previously dispatched. virtual void DispatchScrollEvent(ui::ScrollEvent* event, aura::Window* target) = 0; }; diff --git a/ash/sticky_keys/sticky_keys_unittest.cc b/ash/sticky_keys/sticky_keys_unittest.cc index 8f7a2a3..937cfd4 100644 --- a/ash/sticky_keys/sticky_keys_unittest.cc +++ b/ash/sticky_keys/sticky_keys_unittest.cc @@ -245,26 +245,38 @@ class StickyKeysTest : public test::AshTestBase, } // Creates a synthesized MouseEvent that is not backed by a native event. - ui::MouseEvent* GenerateSynthesizedMouseEvent(bool is_button_press) { - ui::MouseEvent* event = new ui::MouseEvent( - is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, - gfx::Point(0, 0), - gfx::Point(0, 0), - ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_LEFT_MOUSE_BUTTON); + ui::MouseEvent* GenerateSynthesizedMouseEventAt(ui::EventType event_type, + const gfx::Point& location) { + ui::MouseEvent* event = new ui::MouseEvent(event_type, + location, + location, + ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_LEFT_MOUSE_BUTTON); ui::Event::DispatcherApi dispatcher(event); dispatcher.set_target(target_); return event; } + // Creates a synthesized mouse press or release event. + ui::MouseEvent* GenerateSynthesizedMouseClickEvent( + bool is_button_press, + const gfx::Point& location) { + return GenerateSynthesizedMouseEventAt( + is_button_press ? ui::ET_MOUSE_PRESSED : ui::ET_MOUSE_RELEASED, + location); + } + // Creates a synthesized ET_MOUSE_MOVED event. - ui::MouseEvent* GenerateSynthesizedMouseEvent(int x, int y) { - ui::MouseEvent* event = new ui::MouseEvent( - ui::ET_MOUSE_MOVED, - gfx::Point(x, y), - gfx::Point(x, y), - ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_LEFT_MOUSE_BUTTON); + ui::MouseEvent* GenerateSynthesizedMouseMoveEvent( + const gfx::Point& location) { + return GenerateSynthesizedMouseEventAt(ui::ET_MOUSE_MOVED, location); + } + + // Creates a synthesized MouseWHeel event. + ui::MouseWheelEvent* GenerateSynthesizedMouseWheelEvent(int wheel_delta) { + scoped_ptr<ui::MouseEvent> mev( + GenerateSynthesizedMouseEventAt(ui::ET_MOUSEWHEEL, gfx::Point(0, 0))); + ui::MouseWheelEvent* event = new ui::MouseWheelEvent(*mev, 0, wheel_delta); ui::Event::DispatcherApi dispatcher(event); dispatcher.set_target(target_); return event; @@ -491,9 +503,9 @@ TEST_F(StickyKeysTest, MouseMovedModifierTest) { // Press ctrl and handle mouse move events. kev.reset(GenerateKey(true, ui::VKEY_CONTROL)); sticky_key.HandleKeyEvent(kev.get()); - mev.reset(GenerateSynthesizedMouseEvent(0, 0)); + mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(0, 0))); sticky_key.HandleMouseEvent(mev.get()); - mev.reset(GenerateSynthesizedMouseEvent(100, 100)); + mev.reset(GenerateSynthesizedMouseMoveEvent(gfx::Point(100, 100))); sticky_key.HandleMouseEvent(mev.get()); // Sticky keys should be enabled afterwards. @@ -780,12 +792,12 @@ TEST_F(StickyKeysTest, SynthesizedEvents) { EXPECT_EQ(STICKY_KEY_STATE_ENABLED, sticky_key.current_state()); scoped_ptr<ui::MouseEvent> mev; - mev.reset(GenerateSynthesizedMouseEvent(true)); + 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(GenerateSynthesizedMouseEvent(false)); + 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()); @@ -828,6 +840,21 @@ TEST_F(StickyKeysTest, KeyEventDispatchImpl) { 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)); + dispatcher->OnEventFromSource(kev.get()); + 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); } @@ -881,6 +908,21 @@ TEST_P(StickyKeysMouseDispatchTest, MouseEventDispatchImpl) { 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)); + dispatcher->OnEventFromSource(ev.get()); + 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); } @@ -935,6 +977,23 @@ TEST_P(StickyKeysMouseDispatchTest, MouseWheelEventDispatchImpl) { 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)); + dispatcher->OnEventFromSource(ev.get()); + 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); } |