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 "content/browser/renderer_host/web_input_event_aura.h"
7 #include "base/basictypes.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_utils.h"
11 #include "ui/events/keycodes/dom/dom_code.h"
12 #include "ui/events/keycodes/dom/dom_key.h"
13 #include "ui/events/keycodes/dom/keycode_converter.h"
16 #include <X11/keysym.h>
18 #include "ui/events/test/events_test_utils_x11.h"
19 #include "ui/gfx/x/x11_types.h"
24 // Checks that MakeWebKeyboardEvent makes a DOM3 spec compliant key event.
26 TEST(WebInputEventAuraTest
, TestMakeWebKeyboardEvent
) {
29 ui::KeyEvent
event(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
,
30 ui::DomCode::CONTROL_LEFT
, ui::EF_CONTROL_DOWN
);
31 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
32 // However, modifier bit for Control in |webkit_event| should be set.
33 EXPECT_EQ(blink::WebInputEvent::ControlKey
| blink::WebInputEvent::IsLeft
,
34 webkit_event
.modifiers
);
35 EXPECT_EQ(static_cast<int>(ui::DomCode::CONTROL_LEFT
),
36 webkit_event
.domCode
);
40 ui::KeyEvent
event(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
,
41 ui::DomCode::CONTROL_LEFT
, ui::EF_NONE
);
42 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
43 // However, modifier bit for Control in |webkit_event| shouldn't be set.
44 EXPECT_EQ(blink::WebInputEvent::IsLeft
, webkit_event
.modifiers
);
45 EXPECT_EQ(static_cast<int>(ui::DomCode::CONTROL_LEFT
),
46 webkit_event
.domCode
);
49 const int kLocationModifiers
=
50 blink::WebInputEvent::IsLeft
| blink::WebInputEvent::IsRight
;
51 ui::ScopedXI2Event xev
;
54 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
55 ui::KeyEvent
event(xev
);
56 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
57 // However, modifier bit for Control in |webkit_event| should be set.
58 EXPECT_EQ(blink::WebInputEvent::ControlKey
,
59 webkit_event
.modifiers
& ~kLocationModifiers
);
63 xev
.InitKeyEvent(ui::ET_KEY_RELEASED
, ui::VKEY_CONTROL
, ControlMask
);
64 ui::KeyEvent
event(xev
);
65 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
66 // However, modifier bit for Control in |webkit_event| shouldn't be set.
67 EXPECT_EQ(0, webkit_event
.modifiers
& ~kLocationModifiers
);
72 // Checks that MakeWebKeyboardEvent returns a correct windowsKeyCode.
73 #if defined(OS_CHROMEOS) || defined(THREAD_SANITIZER)
74 // Fails on Chrome OS and under ThreadSanitizer on Linux, see
75 // https://crbug.com/449103.
76 #define MAYBE_TestMakeWebKeyboardEventWindowsKeyCode \
77 DISABLED_TestMakeWebKeyboardEventWindowsKeyCode
79 #define MAYBE_TestMakeWebKeyboardEventWindowsKeyCode \
80 TestMakeWebKeyboardEventWindowsKeyCode
82 TEST(WebInputEventAuraTest
, MAYBE_TestMakeWebKeyboardEventWindowsKeyCode
) {
84 ui::ScopedXI2Event xev
;
87 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
89 xevent
->xkey
.keycode
=
90 ui::KeycodeConverter::DomCodeToNativeKeycode(ui::DomCode::CONTROL_LEFT
);
91 ui::KeyEvent
event(xev
);
92 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
93 // ui::VKEY_LCONTROL, instead of ui::VKEY_CONTROL, should be filled.
94 EXPECT_EQ(ui::VKEY_LCONTROL
, webkit_event
.windowsKeyCode
);
98 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
, 0);
100 xevent
->xkey
.keycode
= ui::KeycodeConverter::DomCodeToNativeKeycode(
101 ui::DomCode::CONTROL_RIGHT
);
102 ui::KeyEvent
event(xev
);
103 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
104 // ui::VKEY_RCONTROL, instead of ui::VKEY_CONTROL, should be filled.
105 EXPECT_EQ(ui::VKEY_RCONTROL
, webkit_event
.windowsKeyCode
);
107 #elif defined(OS_WIN)
108 // TODO(yusukes): Add tests for win_aura once keyboardEvent() in
109 // third_party/WebKit/Source/web/win/WebInputEventFactory.cpp is modified
110 // to return VKEY_[LR]XXX instead of VKEY_XXX.
111 // https://bugs.webkit.org/show_bug.cgi?id=86694
115 ui::KeyEvent
event(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
,
116 ui::DomCode::CONTROL_LEFT
, ui::EF_CONTROL_DOWN
,
117 ui::DomKey::CONTROL
, 0, ui::EventTimeForNow());
118 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
119 // ui::VKEY_LCONTROL, instead of ui::VKEY_CONTROL, should be filled.
120 EXPECT_EQ(ui::VKEY_LCONTROL
, webkit_event
.windowsKeyCode
);
124 ui::KeyEvent
event(ui::ET_KEY_PRESSED
, ui::VKEY_CONTROL
,
125 ui::DomCode::CONTROL_RIGHT
, ui::EF_CONTROL_DOWN
,
126 ui::DomKey::CONTROL
, 0, ui::EventTimeForNow());
127 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
128 // ui::VKEY_RCONTROL, instead of ui::VKEY_CONTROL, should be filled.
129 EXPECT_EQ(ui::VKEY_RCONTROL
, webkit_event
.windowsKeyCode
);
133 // Checks that MakeWebKeyboardEvent fills a correct keypad modifier.
134 TEST(WebInputEventAuraTest
, TestMakeWebKeyboardEventKeyPadKeyCode
) {
141 ui::DomCode dom_code
; // The physical key (location).
142 ui::KeyboardCode ui_keycode
; // The virtual key code.
143 uint32 x_keysym
; // The X11 keysym.
144 bool expected_result
; // true if the event has "isKeyPad" modifier.
146 {ui::DomCode::DIGIT0
, ui::VKEY_0
, XK(0), false},
147 {ui::DomCode::DIGIT1
, ui::VKEY_1
, XK(1), false},
148 {ui::DomCode::DIGIT2
, ui::VKEY_2
, XK(2), false},
149 {ui::DomCode::DIGIT3
, ui::VKEY_3
, XK(3), false},
150 {ui::DomCode::DIGIT4
, ui::VKEY_4
, XK(4), false},
151 {ui::DomCode::DIGIT5
, ui::VKEY_5
, XK(5), false},
152 {ui::DomCode::DIGIT6
, ui::VKEY_6
, XK(6), false},
153 {ui::DomCode::DIGIT7
, ui::VKEY_7
, XK(7), false},
154 {ui::DomCode::DIGIT8
, ui::VKEY_8
, XK(8), false},
155 {ui::DomCode::DIGIT9
, ui::VKEY_9
, XK(9), false},
157 {ui::DomCode::NUMPAD0
, ui::VKEY_NUMPAD0
, XK(KP_0
), true},
158 {ui::DomCode::NUMPAD1
, ui::VKEY_NUMPAD1
, XK(KP_1
), true},
159 {ui::DomCode::NUMPAD2
, ui::VKEY_NUMPAD2
, XK(KP_2
), true},
160 {ui::DomCode::NUMPAD3
, ui::VKEY_NUMPAD3
, XK(KP_3
), true},
161 {ui::DomCode::NUMPAD4
, ui::VKEY_NUMPAD4
, XK(KP_4
), true},
162 {ui::DomCode::NUMPAD5
, ui::VKEY_NUMPAD5
, XK(KP_5
), true},
163 {ui::DomCode::NUMPAD6
, ui::VKEY_NUMPAD6
, XK(KP_6
), true},
164 {ui::DomCode::NUMPAD7
, ui::VKEY_NUMPAD7
, XK(KP_7
), true},
165 {ui::DomCode::NUMPAD8
, ui::VKEY_NUMPAD8
, XK(KP_8
), true},
166 {ui::DomCode::NUMPAD9
, ui::VKEY_NUMPAD9
, XK(KP_9
), true},
168 {ui::DomCode::NUMPAD_MULTIPLY
, ui::VKEY_MULTIPLY
, XK(KP_Multiply
), true},
169 {ui::DomCode::NUMPAD_SUBTRACT
, ui::VKEY_SUBTRACT
, XK(KP_Subtract
), true},
170 {ui::DomCode::NUMPAD_ADD
, ui::VKEY_ADD
, XK(KP_Add
), true},
171 {ui::DomCode::NUMPAD_DIVIDE
, ui::VKEY_DIVIDE
, XK(KP_Divide
), true},
172 {ui::DomCode::NUMPAD_DECIMAL
, ui::VKEY_DECIMAL
, XK(KP_Decimal
), true},
173 {ui::DomCode::NUMPAD_DECIMAL
, ui::VKEY_DELETE
, XK(KP_Delete
), true},
174 {ui::DomCode::NUMPAD0
, ui::VKEY_INSERT
, XK(KP_Insert
), true},
175 {ui::DomCode::NUMPAD1
, ui::VKEY_END
, XK(KP_End
), true},
176 {ui::DomCode::NUMPAD2
, ui::VKEY_DOWN
, XK(KP_Down
), true},
177 {ui::DomCode::NUMPAD3
, ui::VKEY_NEXT
, XK(KP_Page_Down
), true},
178 {ui::DomCode::NUMPAD4
, ui::VKEY_LEFT
, XK(KP_Left
), true},
179 {ui::DomCode::NUMPAD5
, ui::VKEY_CLEAR
, XK(KP_Begin
), true},
180 {ui::DomCode::NUMPAD6
, ui::VKEY_RIGHT
, XK(KP_Right
), true},
181 {ui::DomCode::NUMPAD7
, ui::VKEY_HOME
, XK(KP_Home
), true},
182 {ui::DomCode::NUMPAD8
, ui::VKEY_UP
, XK(KP_Up
), true},
183 {ui::DomCode::NUMPAD9
, ui::VKEY_PRIOR
, XK(KP_Page_Up
), true},
185 for (const auto& test_case
: kTesCases
) {
186 ui::KeyEvent
event(ui::ET_KEY_PRESSED
, test_case
.ui_keycode
,
187 test_case
.dom_code
, ui::EF_NONE
);
188 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
189 EXPECT_EQ(test_case
.expected_result
,
190 (webkit_event
.modifiers
& blink::WebInputEvent::IsKeyPad
) != 0)
193 << ui::KeycodeConverter::DomCodeToCodeString(test_case
.dom_code
)
194 << ", ui_keycode:" << test_case
.ui_keycode
195 << "}, expect: " << test_case
.expected_result
;
198 ui::ScopedXI2Event xev
;
199 for (size_t i
= 0; i
< arraysize(kTesCases
); ++i
) {
200 const TestCase
& test_case
= kTesCases
[i
];
202 // TODO: re-enable the two cases excluded here once all trybots
203 // are sufficiently up to date to round-trip the associated keys.
204 if ((test_case
.x_keysym
== XK_KP_Divide
) ||
205 (test_case
.x_keysym
== XK_KP_Decimal
))
208 xev
.InitKeyEvent(ui::ET_KEY_PRESSED
, test_case
.ui_keycode
, ui::EF_NONE
);
209 XEvent
* xevent
= xev
;
210 xevent
->xkey
.keycode
=
211 XKeysymToKeycode(gfx::GetXDisplay(), test_case
.x_keysym
);
212 if (!xevent
->xkey
.keycode
)
214 ui::KeyEvent
event(xev
);
215 blink::WebKeyboardEvent webkit_event
= MakeWebKeyboardEvent(event
);
216 EXPECT_EQ(test_case
.expected_result
,
217 (webkit_event
.modifiers
& blink::WebInputEvent::IsKeyPad
) != 0)
218 << "Failed in " << i
<< "th test case: "
220 << ui::KeycodeConverter::DomCodeToCodeString(test_case
.dom_code
)
221 << ", ui_keycode:" << test_case
.ui_keycode
222 << ", x_keysym:" << test_case
.x_keysym
223 << "}, expect: " << test_case
.expected_result
;
228 } // namespace content