OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/memory/scoped_ptr.h" | 5 #include "base/memory/scoped_ptr.h" |
6 #include "testing/gtest/include/gtest/gtest.h" | 6 #include "testing/gtest/include/gtest/gtest.h" |
7 #include "ui/events/event.h" | 7 #include "ui/events/event.h" |
8 #include "ui/events/event_utils.h" | 8 #include "ui/events/event_utils.h" |
9 #include "ui/events/keycodes/dom4/keycode_converter.h" | 9 #include "ui/events/keycodes/dom/dom_code.h" |
| 10 #include "ui/events/keycodes/dom/keycode_converter.h" |
10 #include "ui/events/test/events_test_utils.h" | 11 #include "ui/events/test/events_test_utils.h" |
11 | 12 |
12 #if defined(USE_X11) | 13 #if defined(USE_X11) |
13 #include <X11/Xlib.h> | 14 #include <X11/Xlib.h> |
14 #include "ui/events/test/events_test_utils_x11.h" | 15 #include "ui/events/test/events_test_utils_x11.h" |
15 #include "ui/gfx/x/x11_types.h" | 16 #include "ui/gfx/x/x11_types.h" |
16 #endif | 17 #endif |
17 | 18 |
18 namespace ui { | 19 namespace ui { |
19 | 20 |
| 21 TEST(EventTest, NoNativeEvent) { |
| 22 KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE); |
| 23 EXPECT_FALSE(keyev.HasNativeEvent()); |
| 24 } |
| 25 |
| 26 TEST(EventTest, NativeEvent) { |
| 27 #if defined(OS_WIN) |
| 28 MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 }; |
| 29 KeyEvent keyev(native_event); |
| 30 EXPECT_TRUE(keyev.HasNativeEvent()); |
| 31 #elif defined(USE_X11) |
| 32 ScopedXI2Event event; |
| 33 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, EF_NONE); |
| 34 KeyEvent keyev(event); |
| 35 EXPECT_TRUE(keyev.HasNativeEvent()); |
| 36 #endif |
| 37 } |
| 38 |
20 TEST(EventTest, GetCharacter) { | 39 TEST(EventTest, GetCharacter) { |
21 // Check if Control+Enter returns 10. | 40 // Check if Control+Enter returns 10. |
22 KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN); | 41 KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN); |
23 EXPECT_EQ(10, keyev1.GetCharacter()); | 42 EXPECT_EQ(10, keyev1.GetCharacter()); |
24 // Check if Enter returns 13. | 43 // Check if Enter returns 13. |
25 KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE); | 44 KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE); |
26 EXPECT_EQ(13, keyev2.GetCharacter()); | 45 EXPECT_EQ(13, keyev2.GetCharacter()); |
| 46 |
| 47 #if defined(USE_X11) |
| 48 // For X11, test the functions with native_event() as well. crbug.com/107837 |
| 49 ScopedXI2Event event; |
| 50 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN); |
| 51 KeyEvent keyev3(event); |
| 52 EXPECT_EQ(10, keyev3.GetCharacter()); |
| 53 |
| 54 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_RETURN, EF_NONE); |
| 55 KeyEvent keyev4(event); |
| 56 EXPECT_EQ(13, keyev4.GetCharacter()); |
| 57 #endif |
27 } | 58 } |
28 | 59 |
29 TEST(EventTest, ClickCount) { | 60 TEST(EventTest, ClickCount) { |
30 const gfx::Point origin(0, 0); | 61 const gfx::Point origin(0, 0); |
31 MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, 0, 0); | 62 MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, 0); |
32 for (int i = 1; i <=3 ; ++i) { | 63 for (int i = 1; i <=3 ; ++i) { |
33 mouseev.SetClickCount(i); | 64 mouseev.SetClickCount(i); |
34 EXPECT_EQ(i, mouseev.GetClickCount()); | 65 EXPECT_EQ(i, mouseev.GetClickCount()); |
35 } | 66 } |
36 } | 67 } |
37 | 68 |
38 TEST(EventTest, RepeatedClick) { | 69 TEST(EventTest, RepeatedClick) { |
39 const gfx::Point origin(0, 0); | 70 const gfx::Point origin(0, 0); |
40 MouseEvent mouse_ev1(ET_MOUSE_PRESSED, origin, origin, 0, 0); | 71 MouseEvent mouse_ev1(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, |
41 MouseEvent mouse_ev2(ET_MOUSE_PRESSED, origin, origin, 0, 0); | 72 0); |
| 73 MouseEvent mouse_ev2(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), 0, |
| 74 0); |
42 LocatedEventTestApi test_ev1(&mouse_ev1); | 75 LocatedEventTestApi test_ev1(&mouse_ev1); |
43 LocatedEventTestApi test_ev2(&mouse_ev2); | 76 LocatedEventTestApi test_ev2(&mouse_ev2); |
44 | 77 |
45 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); | 78 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); |
46 base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1); | 79 base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1); |
47 base::TimeDelta later = start + base::TimeDelta::FromMilliseconds(1000); | 80 base::TimeDelta later = start + base::TimeDelta::FromMilliseconds(1000); |
48 | 81 |
| 82 // Same event. |
| 83 test_ev1.set_location(gfx::Point(0, 0)); |
| 84 test_ev2.set_location(gfx::Point(1, 0)); |
| 85 test_ev1.set_time_stamp(start); |
| 86 test_ev2.set_time_stamp(start); |
| 87 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); |
| 88 MouseEvent mouse_ev3(mouse_ev1); |
| 89 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev3)); |
| 90 |
49 // Close point. | 91 // Close point. |
50 test_ev1.set_location(gfx::Point(0, 0)); | 92 test_ev1.set_location(gfx::Point(0, 0)); |
51 test_ev2.set_location(gfx::Point(1, 0)); | 93 test_ev2.set_location(gfx::Point(1, 0)); |
52 test_ev1.set_time_stamp(start); | 94 test_ev1.set_time_stamp(start); |
53 test_ev2.set_time_stamp(soon); | 95 test_ev2.set_time_stamp(soon); |
54 EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); | 96 EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); |
55 | 97 |
56 // Too far. | 98 // Too far. |
57 test_ev1.set_location(gfx::Point(0, 0)); | 99 test_ev1.set_location(gfx::Point(0, 0)); |
58 test_ev2.set_location(gfx::Point(10, 0)); | 100 test_ev2.set_location(gfx::Point(10, 0)); |
59 test_ev1.set_time_stamp(start); | 101 test_ev1.set_time_stamp(start); |
60 test_ev2.set_time_stamp(soon); | 102 test_ev2.set_time_stamp(soon); |
61 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); | 103 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); |
62 | 104 |
63 // Too long a time between clicks. | 105 // Too long a time between clicks. |
64 test_ev1.set_location(gfx::Point(0, 0)); | 106 test_ev1.set_location(gfx::Point(0, 0)); |
65 test_ev2.set_location(gfx::Point(0, 0)); | 107 test_ev2.set_location(gfx::Point(0, 0)); |
66 test_ev1.set_time_stamp(start); | 108 test_ev1.set_time_stamp(start); |
67 test_ev2.set_time_stamp(later); | 109 test_ev2.set_time_stamp(later); |
68 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); | 110 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2)); |
69 } | 111 } |
70 | 112 |
| 113 // Tests that an event only increases the click count and gets marked as a |
| 114 // double click if a release event was seen for the previous click. This |
| 115 // prevents the same PRESSED event from being processed twice: |
| 116 // http://crbug.com/389162 |
| 117 TEST(EventTest, DoubleClickRequiresRelease) { |
| 118 const gfx::Point origin1(0, 0); |
| 119 const gfx::Point origin2(100, 0); |
| 120 scoped_ptr<MouseEvent> ev; |
| 121 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); |
| 122 base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1); |
| 123 |
| 124 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin1, origin1, EventTimeForNow(), |
| 125 0, 0)); |
| 126 ev->set_time_stamp(start); |
| 127 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 128 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin1, origin1, EventTimeForNow(), |
| 129 0, 0)); |
| 130 ev->set_time_stamp(start); |
| 131 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 132 |
| 133 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin2, origin2, EventTimeForNow(), |
| 134 0, 0)); |
| 135 ev->set_time_stamp(start); |
| 136 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 137 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin2, origin2, |
| 138 EventTimeForNow(), 0, 0)); |
| 139 ev->set_time_stamp(start); |
| 140 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 141 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin2, origin2, EventTimeForNow(), |
| 142 0, 0)); |
| 143 ev->set_time_stamp(soon); |
| 144 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev)); |
| 145 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin2, origin2, |
| 146 EventTimeForNow(), 0, 0)); |
| 147 ev->set_time_stamp(soon); |
| 148 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev)); |
| 149 MouseEvent::ResetLastClickForTest(); |
| 150 } |
| 151 |
| 152 // Tests that clicking right and then left clicking does not generate a double |
| 153 // click. |
| 154 TEST(EventTest, SingleClickRightLeft) { |
| 155 const gfx::Point origin(0, 0); |
| 156 scoped_ptr<MouseEvent> ev; |
| 157 base::TimeDelta start = base::TimeDelta::FromMilliseconds(0); |
| 158 base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1); |
| 159 |
| 160 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), |
| 161 ui::EF_RIGHT_MOUSE_BUTTON, |
| 162 ui::EF_RIGHT_MOUSE_BUTTON)); |
| 163 ev->set_time_stamp(start); |
| 164 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 165 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), |
| 166 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); |
| 167 ev->set_time_stamp(start); |
| 168 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 169 ev.reset(new MouseEvent(ET_MOUSE_RELEASED, origin, origin, EventTimeForNow(), |
| 170 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); |
| 171 ev->set_time_stamp(start); |
| 172 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev)); |
| 173 ev.reset(new MouseEvent(ET_MOUSE_PRESSED, origin, origin, EventTimeForNow(), |
| 174 ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON)); |
| 175 ev->set_time_stamp(soon); |
| 176 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev)); |
| 177 MouseEvent::ResetLastClickForTest(); |
| 178 } |
| 179 |
71 TEST(EventTest, KeyEvent) { | 180 TEST(EventTest, KeyEvent) { |
72 static const struct { | 181 static const struct { |
73 KeyboardCode key_code; | 182 KeyboardCode key_code; |
74 int flags; | 183 int flags; |
75 uint16 character; | 184 uint16 character; |
76 } kTestData[] = { | 185 } kTestData[] = { |
77 { VKEY_A, 0, 'a' }, | 186 { VKEY_A, 0, 'a' }, |
78 { VKEY_A, EF_SHIFT_DOWN, 'A' }, | 187 { VKEY_A, EF_SHIFT_DOWN, 'A' }, |
79 { VKEY_A, EF_CAPS_LOCK_DOWN, 'A' }, | 188 { VKEY_A, EF_CAPS_LOCK_DOWN, 'A' }, |
80 { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'a' }, | 189 { VKEY_A, EF_SHIFT_DOWN | EF_CAPS_LOCK_DOWN, 'a' }, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 262 } |
154 | 263 |
155 TEST(EventTest, KeyEventDirectUnicode) { | 264 TEST(EventTest, KeyEventDirectUnicode) { |
156 KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::EF_NONE); | 265 KeyEvent key(0x1234U, ui::VKEY_UNKNOWN, ui::EF_NONE); |
157 EXPECT_EQ(0x1234U, key.GetCharacter()); | 266 EXPECT_EQ(0x1234U, key.GetCharacter()); |
158 EXPECT_EQ(ET_KEY_PRESSED, key.type()); | 267 EXPECT_EQ(ET_KEY_PRESSED, key.type()); |
159 EXPECT_TRUE(key.is_char()); | 268 EXPECT_TRUE(key.is_char()); |
160 } | 269 } |
161 | 270 |
162 TEST(EventTest, NormalizeKeyEventFlags) { | 271 TEST(EventTest, NormalizeKeyEventFlags) { |
| 272 #if defined(USE_X11) |
| 273 // Normalize flags when KeyEvent is created from XEvent. |
| 274 ScopedXI2Event event; |
| 275 { |
| 276 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN); |
| 277 KeyEvent keyev(event); |
| 278 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); |
| 279 } |
| 280 { |
| 281 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN); |
| 282 KeyEvent keyev(event); |
| 283 EXPECT_EQ(EF_NONE, keyev.flags()); |
| 284 } |
| 285 { |
| 286 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_CONTROL, EF_CONTROL_DOWN); |
| 287 KeyEvent keyev(event); |
| 288 EXPECT_EQ(EF_CONTROL_DOWN, keyev.flags()); |
| 289 } |
| 290 { |
| 291 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_CONTROL, EF_CONTROL_DOWN); |
| 292 KeyEvent keyev(event); |
| 293 EXPECT_EQ(EF_NONE, keyev.flags()); |
| 294 } |
| 295 { |
| 296 event.InitKeyEvent(ET_KEY_PRESSED, VKEY_MENU, EF_ALT_DOWN); |
| 297 KeyEvent keyev(event); |
| 298 EXPECT_EQ(EF_ALT_DOWN, keyev.flags()); |
| 299 } |
| 300 { |
| 301 event.InitKeyEvent(ET_KEY_RELEASED, VKEY_MENU, EF_ALT_DOWN); |
| 302 KeyEvent keyev(event); |
| 303 EXPECT_EQ(EF_NONE, keyev.flags()); |
| 304 } |
| 305 #endif |
| 306 |
163 // Do not normalize flags for synthesized events without | 307 // Do not normalize flags for synthesized events without |
164 // KeyEvent::NormalizeFlags called explicitly. | 308 // KeyEvent::NormalizeFlags called explicitly. |
165 { | 309 { |
166 KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN); | 310 KeyEvent keyev(ET_KEY_PRESSED, VKEY_SHIFT, EF_SHIFT_DOWN); |
167 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); | 311 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); |
168 } | 312 } |
169 { | 313 { |
170 KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN); | 314 KeyEvent keyev(ET_KEY_RELEASED, VKEY_SHIFT, EF_SHIFT_DOWN); |
171 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); | 315 EXPECT_EQ(EF_SHIFT_DOWN, keyev.flags()); |
172 keyev.NormalizeFlags(); | 316 keyev.NormalizeFlags(); |
(...skipping 22 matching lines...) Expand all Loading... |
195 } | 339 } |
196 | 340 |
197 TEST(EventTest, KeyEventCopy) { | 341 TEST(EventTest, KeyEventCopy) { |
198 KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE); | 342 KeyEvent key(ET_KEY_PRESSED, VKEY_A, EF_NONE); |
199 scoped_ptr<KeyEvent> copied_key(new KeyEvent(key)); | 343 scoped_ptr<KeyEvent> copied_key(new KeyEvent(key)); |
200 EXPECT_EQ(copied_key->type(), key.type()); | 344 EXPECT_EQ(copied_key->type(), key.type()); |
201 EXPECT_EQ(copied_key->key_code(), key.key_code()); | 345 EXPECT_EQ(copied_key->key_code(), key.key_code()); |
202 } | 346 } |
203 | 347 |
204 TEST(EventTest, KeyEventCode) { | 348 TEST(EventTest, KeyEventCode) { |
| 349 const DomCode kDomCodeForSpace = DomCode::SPACE; |
205 const char kCodeForSpace[] = "Space"; | 350 const char kCodeForSpace[] = "Space"; |
| 351 ASSERT_EQ(kDomCodeForSpace, |
| 352 ui::KeycodeConverter::CodeStringToDomCode(kCodeForSpace)); |
206 const uint16 kNativeCodeSpace = | 353 const uint16 kNativeCodeSpace = |
207 ui::KeycodeConverter::CodeToNativeKeycode(kCodeForSpace); | 354 ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace); |
208 ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace); | 355 ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace); |
209 | 356 ASSERT_EQ(kNativeCodeSpace, |
210 { | 357 ui::KeycodeConverter::DomCodeToNativeKeycode(kDomCodeForSpace)); |
211 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kCodeForSpace, EF_NONE); | 358 |
212 EXPECT_EQ(kCodeForSpace, key.code()); | 359 { |
| 360 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, kDomCodeForSpace, EF_NONE); |
| 361 EXPECT_EQ(kCodeForSpace, key.GetCodeString()); |
213 } | 362 } |
214 { | 363 { |
215 // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be | 364 // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be |
216 // the specified value. | 365 // the specified value. |
217 KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kCodeForSpace, EF_NONE); | 366 KeyEvent key(ET_KEY_PRESSED, VKEY_RETURN, kDomCodeForSpace, EF_NONE); |
218 EXPECT_EQ(kCodeForSpace, key.code()); | 367 EXPECT_EQ(kCodeForSpace, key.GetCodeString()); |
219 } | 368 } |
220 { | 369 { |
221 // If the synthetic event is initialized without code, it returns | 370 // If the synthetic event is initialized without code, the code is |
222 // an empty string. | 371 // determined from the KeyboardCode assuming a US keyboard layout. |
223 // TODO(komatsu): Fill a fallback value assuming the US keyboard layout. | |
224 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE); | 372 KeyEvent key(ET_KEY_PRESSED, VKEY_SPACE, EF_NONE); |
225 EXPECT_TRUE(key.code().empty()); | 373 EXPECT_EQ(kCodeForSpace, key.GetCodeString()); |
226 } | 374 } |
227 } | 375 #if defined(USE_X11) |
228 | 376 { |
| 377 // KeyEvent converts from the native keycode (XKB) to the code. |
| 378 ScopedXI2Event xevent; |
| 379 xevent.InitKeyEvent(ET_KEY_PRESSED, VKEY_SPACE, kNativeCodeSpace); |
| 380 KeyEvent key(xevent); |
| 381 EXPECT_EQ(kCodeForSpace, key.GetCodeString()); |
| 382 } |
| 383 #endif // USE_X11 |
| 384 #if defined(OS_WIN) |
| 385 { |
| 386 // Test a non extended key. |
| 387 ASSERT_EQ((kNativeCodeSpace & 0xFF), kNativeCodeSpace); |
| 388 |
| 389 const LPARAM lParam = GetLParamFromScanCode(kNativeCodeSpace); |
| 390 MSG native_event = { NULL, WM_KEYUP, VKEY_SPACE, lParam }; |
| 391 KeyEvent key(native_event); |
| 392 |
| 393 // KeyEvent converts from the native keycode (scan code) to the code. |
| 394 EXPECT_EQ(kCodeForSpace, key.GetCodeString()); |
| 395 } |
| 396 { |
| 397 const char kCodeForHome[] = "Home"; |
| 398 const uint16 kNativeCodeHome = 0xe047; |
| 399 |
| 400 // 'Home' is an extended key with 0xe000 bits. |
| 401 ASSERT_NE((kNativeCodeHome & 0xFF), kNativeCodeHome); |
| 402 const LPARAM lParam = GetLParamFromScanCode(kNativeCodeHome); |
| 403 |
| 404 MSG native_event = { NULL, WM_KEYUP, VKEY_HOME, lParam }; |
| 405 KeyEvent key(native_event); |
| 406 |
| 407 // KeyEvent converts from the native keycode (scan code) to the code. |
| 408 EXPECT_EQ(kCodeForHome, key.GetCodeString()); |
| 409 } |
| 410 #endif // OS_WIN |
| 411 } |
| 412 |
| 413 namespace { |
| 414 #if defined(USE_X11) |
| 415 void SetKeyEventTimestamp(XEvent* event, long time) { |
| 416 event->xkey.time = time; |
| 417 } |
| 418 |
| 419 void AdvanceKeyEventTimestamp(XEvent* event) { |
| 420 event->xkey.time++; |
| 421 } |
| 422 |
| 423 #elif defined(OS_WIN) |
| 424 void SetKeyEventTimestamp(MSG& msg, long time) { |
| 425 msg.time = time; |
| 426 } |
| 427 |
| 428 void AdvanceKeyEventTimestamp(MSG& msg) { |
| 429 msg.time++; |
| 430 } |
| 431 #endif |
| 432 } // namespace |
| 433 |
| 434 #if defined(USE_X11) || defined(OS_WIN) |
| 435 TEST(EventTest, AutoRepeat) { |
| 436 const uint16 kNativeCodeA = |
| 437 ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::KEY_A); |
| 438 const uint16 kNativeCodeB = |
| 439 ui::KeycodeConverter::DomCodeToNativeKeycode(DomCode::KEY_B); |
| 440 #if defined(USE_X11) |
| 441 ScopedXI2Event native_event_a_pressed; |
| 442 native_event_a_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_A, kNativeCodeA); |
| 443 ScopedXI2Event native_event_a_pressed_1500; |
| 444 native_event_a_pressed_1500.InitKeyEvent( |
| 445 ET_KEY_PRESSED, VKEY_A, kNativeCodeA); |
| 446 ScopedXI2Event native_event_a_pressed_3000; |
| 447 native_event_a_pressed_3000.InitKeyEvent( |
| 448 ET_KEY_PRESSED, VKEY_A, kNativeCodeA); |
| 449 |
| 450 ScopedXI2Event native_event_a_released; |
| 451 native_event_a_released.InitKeyEvent(ET_KEY_RELEASED, VKEY_A, kNativeCodeA); |
| 452 ScopedXI2Event native_event_b_pressed; |
| 453 native_event_b_pressed.InitKeyEvent(ET_KEY_PRESSED, VKEY_B, kNativeCodeB); |
| 454 ScopedXI2Event native_event_a_pressed_nonstandard_state; |
| 455 native_event_a_pressed_nonstandard_state.InitKeyEvent( |
| 456 ET_KEY_PRESSED, VKEY_A, kNativeCodeA); |
| 457 // IBUS-GTK uses the mask (1 << 25) to detect reposted event. |
| 458 static_cast<XEvent*>(native_event_a_pressed_nonstandard_state)->xkey.state |= |
| 459 1 << 25; |
| 460 #elif defined(OS_WIN) |
| 461 const LPARAM lParam_a = GetLParamFromScanCode(kNativeCodeA); |
| 462 const LPARAM lParam_b = GetLParamFromScanCode(kNativeCodeB); |
| 463 MSG native_event_a_pressed = { NULL, WM_KEYDOWN, VKEY_A, lParam_a }; |
| 464 MSG native_event_a_pressed_1500 = { NULL, WM_KEYDOWN, VKEY_A, lParam_a }; |
| 465 MSG native_event_a_pressed_3000 = { NULL, WM_KEYDOWN, VKEY_A, lParam_a }; |
| 466 MSG native_event_a_released = { NULL, WM_KEYUP, VKEY_A, lParam_a }; |
| 467 MSG native_event_b_pressed = { NULL, WM_KEYUP, VKEY_B, lParam_b }; |
| 468 #endif |
| 469 SetKeyEventTimestamp(native_event_a_pressed_1500, 1500); |
| 470 SetKeyEventTimestamp(native_event_a_pressed_3000, 3000); |
| 471 |
| 472 { |
| 473 KeyEvent key_a1(native_event_a_pressed); |
| 474 EXPECT_FALSE(key_a1.IsRepeat()); |
| 475 |
| 476 KeyEvent key_a1_with_same_event(native_event_a_pressed); |
| 477 EXPECT_FALSE(key_a1_with_same_event.IsRepeat()); |
| 478 |
| 479 KeyEvent key_a1_released(native_event_a_released); |
| 480 EXPECT_FALSE(key_a1_released.IsRepeat()); |
| 481 |
| 482 KeyEvent key_a2(native_event_a_pressed); |
| 483 EXPECT_FALSE(key_a2.IsRepeat()); |
| 484 |
| 485 AdvanceKeyEventTimestamp(native_event_a_pressed); |
| 486 KeyEvent key_a2_repeated(native_event_a_pressed); |
| 487 EXPECT_TRUE(key_a2_repeated.IsRepeat()); |
| 488 |
| 489 KeyEvent key_a2_released(native_event_a_released); |
| 490 EXPECT_FALSE(key_a2_released.IsRepeat()); |
| 491 } |
| 492 |
| 493 // Interleaved with different key press. |
| 494 { |
| 495 KeyEvent key_a3(native_event_a_pressed); |
| 496 EXPECT_FALSE(key_a3.IsRepeat()); |
| 497 |
| 498 KeyEvent key_b(native_event_b_pressed); |
| 499 EXPECT_FALSE(key_b.IsRepeat()); |
| 500 |
| 501 AdvanceKeyEventTimestamp(native_event_a_pressed); |
| 502 KeyEvent key_a3_again(native_event_a_pressed); |
| 503 EXPECT_FALSE(key_a3_again.IsRepeat()); |
| 504 |
| 505 AdvanceKeyEventTimestamp(native_event_a_pressed); |
| 506 KeyEvent key_a3_repeated(native_event_a_pressed); |
| 507 EXPECT_TRUE(key_a3_repeated.IsRepeat()); |
| 508 |
| 509 AdvanceKeyEventTimestamp(native_event_a_pressed); |
| 510 KeyEvent key_a3_repeated2(native_event_a_pressed); |
| 511 EXPECT_TRUE(key_a3_repeated2.IsRepeat()); |
| 512 |
| 513 KeyEvent key_a3_released(native_event_a_released); |
| 514 EXPECT_FALSE(key_a3_released.IsRepeat()); |
| 515 } |
| 516 |
| 517 // Hold the key longer than max auto repeat timeout. |
| 518 { |
| 519 KeyEvent key_a4_0(native_event_a_pressed); |
| 520 EXPECT_FALSE(key_a4_0.IsRepeat()); |
| 521 |
| 522 KeyEvent key_a4_1500(native_event_a_pressed_1500); |
| 523 EXPECT_TRUE(key_a4_1500.IsRepeat()); |
| 524 |
| 525 KeyEvent key_a4_3000(native_event_a_pressed_3000); |
| 526 EXPECT_TRUE(key_a4_3000.IsRepeat()); |
| 527 |
| 528 KeyEvent key_a4_released(native_event_a_released); |
| 529 EXPECT_FALSE(key_a4_released.IsRepeat()); |
| 530 } |
| 531 |
| 532 #if defined(USE_X11) |
| 533 { |
| 534 KeyEvent key_a4_pressed(native_event_a_pressed); |
| 535 EXPECT_FALSE(key_a4_pressed.IsRepeat()); |
| 536 |
| 537 KeyEvent key_a4_pressed_nonstandard_state( |
| 538 native_event_a_pressed_nonstandard_state); |
| 539 EXPECT_FALSE(key_a4_pressed_nonstandard_state.IsRepeat()); |
| 540 } |
| 541 #endif |
| 542 } |
| 543 #endif // USE_X11 || OS_WIN |
| 544 |
| 545 TEST(EventTest, TouchEventRadiusDefaultsToOtherAxis) { |
| 546 const base::TimeDelta time = base::TimeDelta::FromMilliseconds(0); |
| 547 const float non_zero_length1 = 30; |
| 548 const float non_zero_length2 = 46; |
| 549 |
| 550 TouchEvent event1(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 551 non_zero_length1, 0, 0, 0); |
| 552 EXPECT_EQ(non_zero_length1, event1.radius_x()); |
| 553 EXPECT_EQ(non_zero_length1, event1.radius_y()); |
| 554 |
| 555 TouchEvent event2(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 556 0, non_zero_length2, 0, 0); |
| 557 EXPECT_EQ(non_zero_length2, event2.radius_x()); |
| 558 EXPECT_EQ(non_zero_length2, event2.radius_y()); |
| 559 } |
| 560 |
| 561 TEST(EventTest, TouchEventRotationAngleFixing) { |
| 562 const base::TimeDelta time = base::TimeDelta::FromMilliseconds(0); |
| 563 const float radius_x = 20; |
| 564 const float radius_y = 10; |
| 565 |
| 566 { |
| 567 const float angle_in_range = 0; |
| 568 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 569 radius_x, radius_y, angle_in_range, 0); |
| 570 EXPECT_FLOAT_EQ(angle_in_range, event.rotation_angle()); |
| 571 } |
| 572 |
| 573 { |
| 574 const float angle_in_range = 179.9f; |
| 575 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 576 radius_x, radius_y, angle_in_range, 0); |
| 577 EXPECT_FLOAT_EQ(angle_in_range, event.rotation_angle()); |
| 578 } |
| 579 |
| 580 { |
| 581 const float angle_negative = -0.1f; |
| 582 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 583 radius_x, radius_y, angle_negative, 0); |
| 584 EXPECT_FLOAT_EQ(180 - 0.1f, event.rotation_angle()); |
| 585 } |
| 586 |
| 587 { |
| 588 const float angle_negative = -200; |
| 589 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 590 radius_x, radius_y, angle_negative, 0); |
| 591 EXPECT_FLOAT_EQ(360 - 200, event.rotation_angle()); |
| 592 } |
| 593 |
| 594 { |
| 595 const float angle_too_big = 180; |
| 596 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 597 radius_x, radius_y, angle_too_big, 0); |
| 598 EXPECT_FLOAT_EQ(0, event.rotation_angle()); |
| 599 } |
| 600 |
| 601 { |
| 602 const float angle_too_big = 400; |
| 603 TouchEvent event(ui::ET_TOUCH_PRESSED, gfx::Point(0, 0), 0, 0, time, |
| 604 radius_x, radius_y, angle_too_big, 0); |
| 605 EXPECT_FLOAT_EQ(400 - 360, event.rotation_angle()); |
| 606 } |
| 607 } |
| 608 |
229 } // namespace ui | 609 } // namespace ui |
OLD | NEW |