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
3 // found in the LICENSE file.
5 #include "base/memory/scoped_ptr.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "ui/events/event.h"
8 #include "ui/events/event_utils.h"
9 #include "ui/events/keycodes/dom4/keycode_converter.h"
10 #include "ui/events/test/events_test_utils.h"
14 #include "ui/events/test/events_test_utils_x11.h"
15 #include "ui/gfx/x/x11_types.h"
20 TEST(EventTest
, NoNativeEvent
) {
21 KeyEvent
keyev(ET_KEY_PRESSED
, VKEY_SPACE
, EF_NONE
);
22 EXPECT_FALSE(keyev
.HasNativeEvent());
25 TEST(EventTest
, NativeEvent
) {
27 MSG native_event
= { NULL
, WM_KEYUP
, VKEY_A
, 0 };
28 KeyEvent
keyev(native_event
);
29 EXPECT_TRUE(keyev
.HasNativeEvent());
30 #elif defined(USE_X11)
32 event
.InitKeyEvent(ET_KEY_RELEASED
, VKEY_A
, EF_NONE
);
33 KeyEvent
keyev(event
);
34 EXPECT_TRUE(keyev
.HasNativeEvent());
38 TEST(EventTest
, GetCharacter
) {
39 // Check if Control+Enter returns 10.
40 KeyEvent
keyev1(ET_KEY_PRESSED
, VKEY_RETURN
, EF_CONTROL_DOWN
);
41 EXPECT_EQ(10, keyev1
.GetCharacter());
42 // Check if Enter returns 13.
43 KeyEvent
keyev2(ET_KEY_PRESSED
, VKEY_RETURN
, EF_NONE
);
44 EXPECT_EQ(13, keyev2
.GetCharacter());
47 // For X11, test the functions with native_event() as well. crbug.com/107837
49 event
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_RETURN
, EF_CONTROL_DOWN
);
50 KeyEvent
keyev3(event
);
51 EXPECT_EQ(10, keyev3
.GetCharacter());
53 event
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_RETURN
, EF_NONE
);
54 KeyEvent
keyev4(event
);
55 EXPECT_EQ(13, keyev4
.GetCharacter());
59 TEST(EventTest
, ClickCount
) {
60 const gfx::Point
origin(0, 0);
61 MouseEvent
mouseev(ET_MOUSE_PRESSED
, origin
, origin
, 0, 0);
62 for (int i
= 1; i
<=3 ; ++i
) {
63 mouseev
.SetClickCount(i
);
64 EXPECT_EQ(i
, mouseev
.GetClickCount());
68 TEST(EventTest
, RepeatedClick
) {
69 const gfx::Point
origin(0, 0);
70 MouseEvent
mouse_ev1(ET_MOUSE_PRESSED
, origin
, origin
, 0, 0);
71 MouseEvent
mouse_ev2(ET_MOUSE_PRESSED
, origin
, origin
, 0, 0);
72 LocatedEventTestApi
test_ev1(&mouse_ev1
);
73 LocatedEventTestApi
test_ev2(&mouse_ev2
);
75 base::TimeDelta start
= base::TimeDelta::FromMilliseconds(0);
76 base::TimeDelta soon
= start
+ base::TimeDelta::FromMilliseconds(1);
77 base::TimeDelta later
= start
+ base::TimeDelta::FromMilliseconds(1000);
80 test_ev1
.set_location(gfx::Point(0, 0));
81 test_ev2
.set_location(gfx::Point(1, 0));
82 test_ev1
.set_time_stamp(start
);
83 test_ev2
.set_time_stamp(soon
);
84 EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1
, mouse_ev2
));
87 test_ev1
.set_location(gfx::Point(0, 0));
88 test_ev2
.set_location(gfx::Point(10, 0));
89 test_ev1
.set_time_stamp(start
);
90 test_ev2
.set_time_stamp(soon
);
91 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1
, mouse_ev2
));
93 // Too long a time between clicks.
94 test_ev1
.set_location(gfx::Point(0, 0));
95 test_ev2
.set_location(gfx::Point(0, 0));
96 test_ev1
.set_time_stamp(start
);
97 test_ev2
.set_time_stamp(later
);
98 EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1
, mouse_ev2
));
101 // Tests that an event only increases the click count and gets marked as a
102 // double click if a release event was seen for the previous click. This
103 // prevents the same PRESSED event from being processed twice:
104 // http://crbug.com/389162
105 TEST(EventTest
, DoubleClickRequiresRelease
) {
106 const gfx::Point
origin1(0, 0);
107 const gfx::Point
origin2(100, 0);
108 scoped_ptr
<MouseEvent
> ev
;
109 base::TimeDelta start
= base::TimeDelta::FromMilliseconds(0);
111 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin1
, origin1
, 0, 0));
112 ev
->set_time_stamp(start
);
113 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
114 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin1
, origin1
, 0, 0));
115 ev
->set_time_stamp(start
);
116 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
118 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin2
, origin2
, 0, 0));
119 ev
->set_time_stamp(start
);
120 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
121 ev
.reset(new MouseEvent(ET_MOUSE_RELEASED
, origin2
, origin2
, 0, 0));
122 ev
->set_time_stamp(start
);
123 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
124 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin2
, origin2
, 0, 0));
125 ev
->set_time_stamp(start
);
126 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev
));
127 ev
.reset(new MouseEvent(ET_MOUSE_RELEASED
, origin2
, origin2
, 0, 0));
128 ev
->set_time_stamp(start
);
129 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev
));
130 MouseEvent::ResetLastClickForTest();
133 // Tests that clicking right and then left clicking does not generate a double
135 TEST(EventTest
, SingleClickRightLeft
) {
136 const gfx::Point
origin(0, 0);
137 scoped_ptr
<MouseEvent
> ev
;
138 base::TimeDelta start
= base::TimeDelta::FromMilliseconds(0);
140 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin
, origin
,
141 ui::EF_RIGHT_MOUSE_BUTTON
,
142 ui::EF_RIGHT_MOUSE_BUTTON
));
143 ev
->set_time_stamp(start
);
144 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
145 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin
, origin
,
146 ui::EF_LEFT_MOUSE_BUTTON
,
147 ui::EF_LEFT_MOUSE_BUTTON
));
148 ev
->set_time_stamp(start
);
149 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
150 ev
.reset(new MouseEvent(ET_MOUSE_RELEASED
, origin
, origin
,
151 ui::EF_LEFT_MOUSE_BUTTON
,
152 ui::EF_LEFT_MOUSE_BUTTON
));
153 ev
->set_time_stamp(start
);
154 EXPECT_EQ(1, MouseEvent::GetRepeatCount(*ev
));
155 ev
.reset(new MouseEvent(ET_MOUSE_PRESSED
, origin
, origin
,
156 ui::EF_LEFT_MOUSE_BUTTON
,
157 ui::EF_LEFT_MOUSE_BUTTON
));
158 ev
->set_time_stamp(start
);
159 EXPECT_EQ(2, MouseEvent::GetRepeatCount(*ev
));
160 MouseEvent::ResetLastClickForTest();
163 TEST(EventTest
, KeyEvent
) {
164 static const struct {
165 KeyboardCode key_code
;
170 { VKEY_A
, EF_SHIFT_DOWN
, 'A' },
171 { VKEY_A
, EF_CAPS_LOCK_DOWN
, 'A' },
172 { VKEY_A
, EF_SHIFT_DOWN
| EF_CAPS_LOCK_DOWN
, 'a' },
173 { VKEY_A
, EF_CONTROL_DOWN
, 0x01 },
174 { VKEY_A
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\x01' },
176 { VKEY_Z
, EF_SHIFT_DOWN
, 'Z' },
177 { VKEY_Z
, EF_CAPS_LOCK_DOWN
, 'Z' },
178 { VKEY_Z
, EF_SHIFT_DOWN
| EF_CAPS_LOCK_DOWN
, 'z' },
179 { VKEY_Z
, EF_CONTROL_DOWN
, '\x1A' },
180 { VKEY_Z
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\x1A' },
182 { VKEY_2
, EF_CONTROL_DOWN
, '\0' },
183 { VKEY_2
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
184 { VKEY_6
, EF_CONTROL_DOWN
, '\0' },
185 { VKEY_6
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\x1E' },
186 { VKEY_OEM_MINUS
, EF_CONTROL_DOWN
, '\0' },
187 { VKEY_OEM_MINUS
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\x1F' },
188 { VKEY_OEM_4
, EF_CONTROL_DOWN
, '\x1B' },
189 { VKEY_OEM_4
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
190 { VKEY_OEM_5
, EF_CONTROL_DOWN
, '\x1C' },
191 { VKEY_OEM_5
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
192 { VKEY_OEM_6
, EF_CONTROL_DOWN
, '\x1D' },
193 { VKEY_OEM_6
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
194 { VKEY_RETURN
, EF_CONTROL_DOWN
, '\x0A' },
197 { VKEY_0
, EF_SHIFT_DOWN
, ')' },
198 { VKEY_0
, EF_SHIFT_DOWN
| EF_CAPS_LOCK_DOWN
, ')' },
199 { VKEY_0
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
202 { VKEY_9
, EF_SHIFT_DOWN
, '(' },
203 { VKEY_9
, EF_SHIFT_DOWN
| EF_CAPS_LOCK_DOWN
, '(' },
204 { VKEY_9
, EF_SHIFT_DOWN
| EF_CONTROL_DOWN
, '\0' },
206 { VKEY_NUMPAD0
, EF_CONTROL_DOWN
, '\0' },
207 { VKEY_NUMPAD0
, EF_SHIFT_DOWN
, '0' },
209 { VKEY_NUMPAD9
, EF_CONTROL_DOWN
, '\0' },
210 { VKEY_NUMPAD9
, EF_SHIFT_DOWN
, '9' },
212 { VKEY_TAB
, EF_CONTROL_DOWN
, '\0' },
213 { VKEY_TAB
, EF_SHIFT_DOWN
, '\t' },
215 { VKEY_MULTIPLY
, EF_CONTROL_DOWN
, '\0' },
216 { VKEY_MULTIPLY
, EF_SHIFT_DOWN
, '*' },
217 { VKEY_ADD
, EF_CONTROL_DOWN
, '\0' },
218 { VKEY_ADD
, EF_SHIFT_DOWN
, '+' },
219 { VKEY_SUBTRACT
, EF_CONTROL_DOWN
, '\0' },
220 { VKEY_SUBTRACT
, EF_SHIFT_DOWN
, '-' },
221 { VKEY_DECIMAL
, EF_CONTROL_DOWN
, '\0' },
222 { VKEY_DECIMAL
, EF_SHIFT_DOWN
, '.' },
223 { VKEY_DIVIDE
, EF_CONTROL_DOWN
, '\0' },
224 { VKEY_DIVIDE
, EF_SHIFT_DOWN
, '/' },
226 { VKEY_OEM_1
, EF_CONTROL_DOWN
, '\0' },
227 { VKEY_OEM_1
, EF_SHIFT_DOWN
, ':' },
228 { VKEY_OEM_PLUS
, EF_CONTROL_DOWN
, '\0' },
229 { VKEY_OEM_PLUS
, EF_SHIFT_DOWN
, '+' },
230 { VKEY_OEM_COMMA
, EF_CONTROL_DOWN
, '\0' },
231 { VKEY_OEM_COMMA
, EF_SHIFT_DOWN
, '<' },
232 { VKEY_OEM_PERIOD
, EF_CONTROL_DOWN
, '\0' },
233 { VKEY_OEM_PERIOD
, EF_SHIFT_DOWN
, '>' },
234 { VKEY_OEM_3
, EF_CONTROL_DOWN
, '\0' },
235 { VKEY_OEM_3
, EF_SHIFT_DOWN
, '~' },
238 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kTestData
); ++i
) {
239 KeyEvent
key(ET_KEY_PRESSED
,
240 kTestData
[i
].key_code
,
242 EXPECT_EQ(kTestData
[i
].character
, key
.GetCharacter())
243 << " Index:" << i
<< " key_code:" << kTestData
[i
].key_code
;
247 TEST(EventTest
, KeyEventDirectUnicode
) {
248 KeyEvent
key(0x1234U
, ui::VKEY_UNKNOWN
, ui::EF_NONE
);
249 EXPECT_EQ(0x1234U
, key
.GetCharacter());
250 EXPECT_EQ(ET_KEY_PRESSED
, key
.type());
251 EXPECT_TRUE(key
.is_char());
254 TEST(EventTest
, NormalizeKeyEventFlags
) {
256 // Normalize flags when KeyEvent is created from XEvent.
257 ScopedXI2Event event
;
259 event
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_SHIFT
, EF_SHIFT_DOWN
);
260 KeyEvent
keyev(event
);
261 EXPECT_EQ(EF_SHIFT_DOWN
, keyev
.flags());
264 event
.InitKeyEvent(ET_KEY_RELEASED
, VKEY_SHIFT
, EF_SHIFT_DOWN
);
265 KeyEvent
keyev(event
);
266 EXPECT_EQ(EF_NONE
, keyev
.flags());
269 event
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_CONTROL
, EF_CONTROL_DOWN
);
270 KeyEvent
keyev(event
);
271 EXPECT_EQ(EF_CONTROL_DOWN
, keyev
.flags());
274 event
.InitKeyEvent(ET_KEY_RELEASED
, VKEY_CONTROL
, EF_CONTROL_DOWN
);
275 KeyEvent
keyev(event
);
276 EXPECT_EQ(EF_NONE
, keyev
.flags());
279 event
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_MENU
, EF_ALT_DOWN
);
280 KeyEvent
keyev(event
);
281 EXPECT_EQ(EF_ALT_DOWN
, keyev
.flags());
284 event
.InitKeyEvent(ET_KEY_RELEASED
, VKEY_MENU
, EF_ALT_DOWN
);
285 KeyEvent
keyev(event
);
286 EXPECT_EQ(EF_NONE
, keyev
.flags());
290 // Do not normalize flags for synthesized events without
291 // KeyEvent::NormalizeFlags called explicitly.
293 KeyEvent
keyev(ET_KEY_PRESSED
, VKEY_SHIFT
, EF_SHIFT_DOWN
);
294 EXPECT_EQ(EF_SHIFT_DOWN
, keyev
.flags());
297 KeyEvent
keyev(ET_KEY_RELEASED
, VKEY_SHIFT
, EF_SHIFT_DOWN
);
298 EXPECT_EQ(EF_SHIFT_DOWN
, keyev
.flags());
299 keyev
.NormalizeFlags();
300 EXPECT_EQ(EF_NONE
, keyev
.flags());
303 KeyEvent
keyev(ET_KEY_PRESSED
, VKEY_CONTROL
, EF_CONTROL_DOWN
);
304 EXPECT_EQ(EF_CONTROL_DOWN
, keyev
.flags());
307 KeyEvent
keyev(ET_KEY_RELEASED
, VKEY_CONTROL
, EF_CONTROL_DOWN
);
308 EXPECT_EQ(EF_CONTROL_DOWN
, keyev
.flags());
309 keyev
.NormalizeFlags();
310 EXPECT_EQ(EF_NONE
, keyev
.flags());
313 KeyEvent
keyev(ET_KEY_PRESSED
, VKEY_MENU
, EF_ALT_DOWN
);
314 EXPECT_EQ(EF_ALT_DOWN
, keyev
.flags());
317 KeyEvent
keyev(ET_KEY_RELEASED
, VKEY_MENU
, EF_ALT_DOWN
);
318 EXPECT_EQ(EF_ALT_DOWN
, keyev
.flags());
319 keyev
.NormalizeFlags();
320 EXPECT_EQ(EF_NONE
, keyev
.flags());
324 TEST(EventTest
, KeyEventCopy
) {
325 KeyEvent
key(ET_KEY_PRESSED
, VKEY_A
, EF_NONE
);
326 scoped_ptr
<KeyEvent
> copied_key(new KeyEvent(key
));
327 EXPECT_EQ(copied_key
->type(), key
.type());
328 EXPECT_EQ(copied_key
->key_code(), key
.key_code());
331 TEST(EventTest
, KeyEventCode
) {
332 const char kCodeForSpace
[] = "Space";
333 const uint16 kNativeCodeSpace
=
334 ui::KeycodeConverter::CodeToNativeKeycode(kCodeForSpace
);
335 ASSERT_NE(ui::KeycodeConverter::InvalidNativeKeycode(), kNativeCodeSpace
);
338 KeyEvent
key(ET_KEY_PRESSED
, VKEY_SPACE
, kCodeForSpace
, EF_NONE
);
339 EXPECT_EQ(kCodeForSpace
, key
.code());
342 // Regardless the KeyEvent.key_code (VKEY_RETURN), code should be
343 // the specified value.
344 KeyEvent
key(ET_KEY_PRESSED
, VKEY_RETURN
, kCodeForSpace
, EF_NONE
);
345 EXPECT_EQ(kCodeForSpace
, key
.code());
348 // If the synthetic event is initialized without code, it returns
350 // TODO(komatsu): Fill a fallback value assuming the US keyboard layout.
351 KeyEvent
key(ET_KEY_PRESSED
, VKEY_SPACE
, EF_NONE
);
352 EXPECT_TRUE(key
.code().empty());
356 // KeyEvent converts from the native keycode (XKB) to the code.
357 ScopedXI2Event xevent
;
358 xevent
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_SPACE
, kNativeCodeSpace
);
359 KeyEvent
key(xevent
);
360 EXPECT_EQ(kCodeForSpace
, key
.code());
365 // Test a non extended key.
366 ASSERT_EQ((kNativeCodeSpace
& 0xFF), kNativeCodeSpace
);
368 const LPARAM lParam
= GetLParamFromScanCode(kNativeCodeSpace
);
369 MSG native_event
= { NULL
, WM_KEYUP
, VKEY_SPACE
, lParam
};
370 KeyEvent
key(native_event
);
372 // KeyEvent converts from the native keycode (scan code) to the code.
373 EXPECT_EQ(kCodeForSpace
, key
.code());
376 const char kCodeForHome
[] = "Home";
377 const uint16 kNativeCodeHome
= 0xe047;
379 // 'Home' is an extended key with 0xe000 bits.
380 ASSERT_NE((kNativeCodeHome
& 0xFF), kNativeCodeHome
);
381 const LPARAM lParam
= GetLParamFromScanCode(kNativeCodeHome
);
383 MSG native_event
= { NULL
, WM_KEYUP
, VKEY_HOME
, lParam
};
384 KeyEvent
key(native_event
);
386 // KeyEvent converts from the native keycode (scan code) to the code.
387 EXPECT_EQ(kCodeForHome
, key
.code());
392 #if defined(USE_X11) || defined(OS_WIN)
393 TEST(EventTest
, AutoRepeat
) {
394 const uint16 kNativeCodeA
= ui::KeycodeConverter::CodeToNativeKeycode("KeyA");
395 const uint16 kNativeCodeB
= ui::KeycodeConverter::CodeToNativeKeycode("KeyB");
397 ScopedXI2Event native_event_a_pressed
;
398 native_event_a_pressed
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_A
, kNativeCodeA
);
399 ScopedXI2Event native_event_a_released
;
400 native_event_a_released
.InitKeyEvent(ET_KEY_RELEASED
, VKEY_A
, kNativeCodeA
);
401 ScopedXI2Event native_event_b_pressed
;
402 native_event_b_pressed
.InitKeyEvent(ET_KEY_PRESSED
, VKEY_B
, kNativeCodeB
);
403 ScopedXI2Event native_event_a_pressed_nonstandard_state
;
404 native_event_a_pressed_nonstandard_state
.InitKeyEvent(
405 ET_KEY_PRESSED
, VKEY_A
, kNativeCodeA
);
406 // IBUS-GTK uses the mask (1 << 25) to detect reposted event.
407 static_cast<XEvent
*>(native_event_a_pressed_nonstandard_state
)->xkey
.state
|=
409 #elif defined(OS_WIN)
410 const LPARAM lParam_a
= GetLParamFromScanCode(kNativeCodeA
);
411 const LPARAM lParam_b
= GetLParamFromScanCode(kNativeCodeB
);
412 MSG native_event_a_pressed
= { NULL
, WM_KEYDOWN
, VKEY_A
, lParam_a
};
413 MSG native_event_a_released
= { NULL
, WM_KEYUP
, VKEY_A
, lParam_a
};
414 MSG native_event_b_pressed
= { NULL
, WM_KEYUP
, VKEY_B
, lParam_b
};
416 KeyEvent
key_a1(native_event_a_pressed
);
417 EXPECT_FALSE(key_a1
.IsRepeat());
418 KeyEvent
key_a1_released(native_event_a_released
);
419 EXPECT_FALSE(key_a1_released
.IsRepeat());
421 KeyEvent
key_a2(native_event_a_pressed
);
422 EXPECT_FALSE(key_a2
.IsRepeat());
423 KeyEvent
key_a2_repeated(native_event_a_pressed
);
424 EXPECT_TRUE(key_a2_repeated
.IsRepeat());
425 KeyEvent
key_a2_released(native_event_a_released
);
426 EXPECT_FALSE(key_a2_released
.IsRepeat());
428 KeyEvent
key_a3(native_event_a_pressed
);
429 EXPECT_FALSE(key_a3
.IsRepeat());
430 KeyEvent
key_b(native_event_b_pressed
);
431 EXPECT_FALSE(key_b
.IsRepeat());
432 KeyEvent
key_a3_again(native_event_a_pressed
);
433 EXPECT_FALSE(key_a3_again
.IsRepeat());
434 KeyEvent
key_a3_repeated(native_event_a_pressed
);
435 EXPECT_TRUE(key_a3_repeated
.IsRepeat());
436 KeyEvent
key_a3_repeated2(native_event_a_pressed
);
437 EXPECT_TRUE(key_a3_repeated2
.IsRepeat());
438 KeyEvent
key_a3_released(native_event_a_released
);
439 EXPECT_FALSE(key_a3_released
.IsRepeat());
442 KeyEvent
key_a4_pressed(native_event_a_pressed
);
443 EXPECT_FALSE(key_a4_pressed
.IsRepeat());
445 KeyEvent
key_a4_pressed_nonstandard_state(
446 native_event_a_pressed_nonstandard_state
);
447 EXPECT_FALSE(key_a4_pressed_nonstandard_state
.IsRepeat());
450 #endif // USE_X11 || OS_WIN