Index: ui/events/platform/platform_event_builder_x_unittest.cc |
diff --git a/ui/events/platform/platform_event_builder_x_unittest.cc b/ui/events/platform/platform_event_builder_x_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8960f636121264e0683d6e90781879a2b6af40a4 |
--- /dev/null |
+++ b/ui/events/platform/platform_event_builder_x_unittest.cc |
@@ -0,0 +1,250 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/events/platform/platform_event_builder.h" |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/events/event.h" |
+#include "ui/events/keycodes/dom4/keycode_converter.h" |
+#include "ui/events/test/events_test_utils_x11.h" |
+#include "ui/events/x/device_data_manager_x11.h" |
+#include "ui/events/x/touch_factory_x11.h" |
+ |
+namespace ui { |
+ |
+class PlatformEventBuilderXTest : public testing::Test { |
+ public: |
+ PlatformEventBuilderXTest() {} |
+ virtual ~PlatformEventBuilderXTest() {} |
+ |
+ void SetUp() override { |
+ DeviceDataManagerX11::CreateInstance(); |
+ ui::TouchFactory::GetInstance()->ResetForTest(); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(PlatformEventBuilderXTest); |
+}; |
+ |
+TEST_F(PlatformEventBuilderXTest, GetCharacter) { |
+ // For X11, test the functions with native_event() as well. crbug.com/107837 |
+ ScopedXI2Event event; |
+ event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN); |
+ KeyEvent keyev3 = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(10, keyev3.GetCharacter()); |
+ |
+ event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE); |
+ KeyEvent keyev4 = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(13, keyev4.GetCharacter()); |
+} |
+ |
+TEST_F(PlatformEventBuilderXTest, NormalizeKeyEventFlags) { |
+ // Normalize flags when KeyEvent is created from XEvent. |
+ ScopedXI2Event event; |
+ { |
+ event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); |
+ } |
+ { |
+ event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_NONE, keyev.flags()); |
+ } |
+ { |
+ event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags()); |
+ } |
+ { |
+ event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_NONE, keyev.flags()); |
+ } |
+ { |
+ event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_ALT_DOWN, keyev.flags()); |
+ } |
+ { |
+ event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN); |
+ KeyEvent keyev = PlatformEventBuilder::BuildKeyEvent(event); |
+ EXPECT_EQ(EF_NONE, keyev.flags()); |
+ } |
+} |
+ |
+TEST_F(PlatformEventBuilderXTest, KeyEventCode) { |
+ const char kCodeForSpace[] = "Space"; |
+ const uint16 kNativeCodeSpace = |
+ ui::KeycodeConverter::CodeToNativeKeycode(kCodeForSpace); |
+ |
+ // KeyEvent converts from the native keycode (XKB) to the code. |
+ ScopedXI2Event xevent; |
+ xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace); |
+ KeyEvent key = PlatformEventBuilder::BuildKeyEvent(xevent); |
+ EXPECT_EQ(kCodeForSpace, key.code()); |
+} |
+ |
+// TODO(erg): When we bring up mojo on Windows, we'll need to port this test to |
+// Windows too. |
+TEST_F(PlatformEventBuilderXTest, AutoRepeat) { |
+ const uint16 kNativeCodeA = ui::KeycodeConverter::CodeToNativeKeycode("KeyA"); |
+ const uint16 kNativeCodeB = ui::KeycodeConverter::CodeToNativeKeycode("KeyB"); |
+#if defined(USE_X11) |
+ ScopedXI2Event native_event_a_pressed; |
+ native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA); |
+ ScopedXI2Event native_event_a_released; |
+ native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA); |
+ ScopedXI2Event native_event_b_pressed; |
+ native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB); |
+ ScopedXI2Event native_event_a_pressed_nonstandard_state; |
+ native_event_a_pressed_nonstandard_state.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, |
+ kNativeCodeA); |
+ // IBUS-GTK uses the mask (1 << 25) to detect reposted event. |
+ static_cast<XEvent*>(native_event_a_pressed_nonstandard_state)->xkey.state |= |
+ 1 << 25; |
+#elif defined(OS_WIN) |
+ const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA); |
+ const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB); |
+ MSG native_event_a_pressed = {NULL, WM_KEYDOWN, VKEY_A, lParam_a}; |
+ MSG native_event_a_released = {NULL, WM_KEYUP, VKEY_A, lParam_a}; |
+ MSG native_event_b_pressed = {NULL, WM_KEYUP, VKEY_B, lParam_b}; |
+#endif |
+ KeyEvent key_a1 = PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_FALSE(key_a1.IsRepeat()); |
+ KeyEvent key_a1_released = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_released); |
+ EXPECT_FALSE(key_a1_released.IsRepeat()); |
+ |
+ KeyEvent key_a2 = PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_FALSE(key_a2.IsRepeat()); |
+ KeyEvent key_a2_repeated = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_TRUE(key_a2_repeated.IsRepeat()); |
+ KeyEvent key_a2_released = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_released); |
+ EXPECT_FALSE(key_a2_released.IsRepeat()); |
+ |
+ KeyEvent key_a3 = PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_FALSE(key_a3.IsRepeat()); |
+ KeyEvent key_b = PlatformEventBuilder::BuildKeyEvent(native_event_b_pressed); |
+ EXPECT_FALSE(key_b.IsRepeat()); |
+ KeyEvent key_a3_again = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_FALSE(key_a3_again.IsRepeat()); |
+ KeyEvent key_a3_repeated = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_TRUE(key_a3_repeated.IsRepeat()); |
+ KeyEvent key_a3_repeated2 = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_TRUE(key_a3_repeated2.IsRepeat()); |
+ KeyEvent key_a3_released = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_released); |
+ EXPECT_FALSE(key_a3_released.IsRepeat()); |
+ |
+#if defined(USE_X11) |
+ KeyEvent key_a4_pressed = |
+ PlatformEventBuilder::BuildKeyEvent(native_event_a_pressed); |
+ EXPECT_FALSE(key_a4_pressed.IsRepeat()); |
+ |
+ KeyEvent key_a4_pressed_nonstandard_state = |
+ PlatformEventBuilder::BuildKeyEvent( |
+ native_event_a_pressed_nonstandard_state); |
+ EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat()); |
+#endif |
+} |
+ |
+// Tests that an event only increases the click count and gets marked as a |
+// double click if a release event was seen for the previous click. This |
+// prevents the same PRESSED event from being processed twice: |
+// http://crbug.com/389162 |
+TEST_F(PlatformEventBuilderXTest, DoubleClickRequiresRelease) { |
+ const gfx::Point origin1(0, 0); |
+ const gfx::Point origin2(100, 0); |
+ base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); |
+ |
+ unsigned int device_id = 1; |
+ std::vector<unsigned int> device_list; |
+ device_list.push_back(device_id); |
+ TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list); |
+ ScopedXI2Event native_event; |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin1, |
+ EF_LEFT_MOUSE_BUTTON); |
+ MouseEvent event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin1, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin2, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_RELEASED, origin2, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin2, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(2, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_RELEASED, origin2, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(2, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ PlatformEventBuilder::ResetLastClickForTest(); |
+} |
+ |
+// Tests that clicking right and then left clicking does not generate a double |
+// click. |
+TEST_F(PlatformEventBuilderXTest, SingleClickRightLeft) { |
+ const gfx::Point origin(0, 0); |
+ base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); |
+ |
+ unsigned int device_id = 1; |
+ std::vector<unsigned int> device_list; |
+ device_list.push_back(device_id); |
+ TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list); |
+ ScopedXI2Event native_event; |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin, |
+ EF_RIGHT_MOUSE_BUTTON); |
+ MouseEvent event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_RELEASED, origin, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(1, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ |
+ native_event.InitGenericButtonEvent(device_id, ET_MOUSE_PRESSED, origin, |
+ EF_LEFT_MOUSE_BUTTON); |
+ event = PlatformEventBuilder::BuildMouseEvent(native_event); |
+ event.set_time_stamp(start); |
+ EXPECT_EQ(2, PlatformEventBuilder::GetRepeatCount(native_event, event)); |
+ PlatformEventBuilder::ResetLastClickForTest(); |
+} |
+ |
+} // namespace ui |