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/gtk_key_bindings_handler.h"
7 #include <gdk/gdkkeysyms.h>
12 #include "base/basictypes.h"
13 #include "base/file_util.h"
14 #include "base/logging.h"
15 #include "base/path_service.h"
16 #include "base/strings/string_util.h"
17 #include "content/common/edit_command.h"
18 #include "content/public/browser/native_web_keyboard_event.h"
19 #include "content/public/common/content_paths.h"
20 #include "testing/gtest/include/gtest/gtest.h"
24 class GtkKeyBindingsHandlerTest
: public testing::Test
{
31 GtkKeyBindingsHandlerTest()
32 : window_(gtk_window_new(GTK_WINDOW_TOPLEVEL
)),
35 PathService::Get(DIR_TEST_DATA
, >krc
);
36 gtkrc
= gtkrc
.AppendASCII("gtk_key_bindings_test_gtkrc");
37 EXPECT_TRUE(file_util::PathExists(gtkrc
));
39 gtk_rc_parse(gtkrc
.value().c_str());
41 GtkWidget
* fixed
= gtk_fixed_new();
42 handler_
= new GtkKeyBindingsHandler(fixed
);
43 gtk_container_add(GTK_CONTAINER(window_
), fixed
);
44 gtk_widget_show(fixed
);
45 gtk_widget_show(window_
);
47 virtual ~GtkKeyBindingsHandlerTest() {
48 gtk_widget_destroy(window_
);
52 NativeWebKeyboardEvent
NewNativeWebKeyboardEvent(guint keyval
, guint state
) {
54 gdk_keymap_get_for_display(gtk_widget_get_display(window_
));
56 GdkKeymapKey
*keys
= NULL
;
58 if (gdk_keymap_get_entries_for_keyval(keymap
, keyval
, &keys
, &n_keys
)) {
60 event
.type
= GDK_KEY_PRESS
;
65 event
.keyval
= keyval
;
68 event
.hardware_keycode
= keys
[0].keycode
;
69 event
.group
= keys
[0].group
;
70 event
.is_modifier
= 0;
72 return NativeWebKeyboardEvent(reinterpret_cast<GdkEvent
*>(&event
));
74 LOG(ERROR
) << "Failed to create key event for keyval:" << keyval
;
75 return NativeWebKeyboardEvent();
78 void TestKeyBinding(const NativeWebKeyboardEvent
& event
,
79 const EditCommand expected_result
[],
82 ASSERT_TRUE(handler_
->Match(event
, &result
));
83 ASSERT_EQ(size
, result
.size());
84 for (size_t i
= 0; i
< size
; ++i
) {
85 ASSERT_STREQ(expected_result
[i
].name
, result
[i
].name
.c_str());
86 ASSERT_STREQ(expected_result
[i
].value
, result
[i
].value
.c_str());
92 GtkKeyBindingsHandler
* handler_
;
95 TEST_F(GtkKeyBindingsHandlerTest
, MoveCursor
) {
96 static const EditCommand kEditCommands
[] = {
97 // "move-cursor" (logical-positions, -2, 0)
98 { "MoveBackward", "" },
99 { "MoveBackward", "" },
100 // "move-cursor" (logical-positions, 2, 0)
101 { "MoveForward", "" },
102 { "MoveForward", "" },
103 // "move-cursor" (visual-positions, -1, 1)
104 { "MoveLeftAndModifySelection", "" },
105 // "move-cursor" (visual-positions, 1, 1)
106 { "MoveRightAndModifySelection", "" },
107 // "move-cursor" (words, -1, 0)
108 { "MoveWordLeft", "" },
109 // "move-cursor" (words, 1, 0)
110 { "MoveWordRight", "" },
111 // "move-cursor" (display-lines, -1, 0)
113 // "move-cursor" (display-lines, 1, 0)
115 // "move-cursor" (display-line-ends, -1, 0)
116 { "MoveToBeginningOfLine", "" },
117 // "move-cursor" (display-line-ends, 1, 0)
118 { "MoveToEndOfLine", "" },
119 // "move-cursor" (paragraph-ends, -1, 0)
120 { "MoveToBeginningOfParagraph", "" },
121 // "move-cursor" (paragraph-ends, 1, 0)
122 { "MoveToEndOfParagraph", "" },
123 // "move-cursor" (pages, -1, 0)
124 { "MovePageUp", "" },
125 // "move-cursor" (pages, 1, 0)
126 { "MovePageDown", "" },
127 // "move-cursor" (buffer-ends, -1, 0)
128 { "MoveToBeginningOfDocument", "" },
129 // "move-cursor" (buffer-ends, 1, 0)
130 { "MoveToEndOfDocument", "" }
133 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_1
, GDK_CONTROL_MASK
),
134 kEditCommands
, arraysize(kEditCommands
));
137 TEST_F(GtkKeyBindingsHandlerTest
, DeleteFromCursor
) {
138 static const EditCommand kEditCommands
[] = {
139 // "delete-from-cursor" (chars, -2)
140 { "DeleteBackward", "" },
141 { "DeleteBackward", "" },
142 // "delete-from-cursor" (chars, 2)
143 { "DeleteForward", "" },
144 { "DeleteForward", "" },
145 // "delete-from-cursor" (word-ends, -1)
146 { "DeleteWordBackward", "" },
147 // "delete-from-cursor" (word-ends, 1)
148 { "DeleteWordForward", "" },
149 // "delete-from-cursor" (words, -1)
150 { "MoveWordBackward", "" },
151 { "DeleteWordForward", "" },
152 // "delete-from-cursor" (words, 1)
153 { "MoveWordForward", "" },
154 { "DeleteWordBackward", "" },
155 // "delete-from-cursor" (display-lines, -1)
156 { "MoveToBeginningOfLine", "" },
157 { "DeleteToEndOfLine", "" },
158 // "delete-from-cursor" (display-lines, 1)
159 { "MoveToBeginningOfLine", "" },
160 { "DeleteToEndOfLine", "" },
161 // "delete-from-cursor" (display-line-ends, -1)
162 { "DeleteToBeginningOfLine", "" },
163 // "delete-from-cursor" (display-line-ends, 1)
164 { "DeleteToEndOfLine", "" },
165 // "delete-from-cursor" (paragraph-ends, -1)
166 { "DeleteToBeginningOfParagraph", "" },
167 // "delete-from-cursor" (paragraph-ends, 1)
168 { "DeleteToEndOfParagraph", "" },
169 // "delete-from-cursor" (paragraphs, -1)
170 { "MoveToBeginningOfParagraph", "" },
171 { "DeleteToEndOfParagraph", "" },
172 // "delete-from-cursor" (paragraphs, 1)
173 { "MoveToBeginningOfParagraph", "" },
174 { "DeleteToEndOfParagraph", "" },
177 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_2
, GDK_CONTROL_MASK
),
178 kEditCommands
, arraysize(kEditCommands
));
181 TEST_F(GtkKeyBindingsHandlerTest
, OtherActions
) {
182 static const EditCommand kBackspace
[] = {
183 { "DeleteBackward", "" }
185 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_3
, GDK_CONTROL_MASK
),
186 kBackspace
, arraysize(kBackspace
));
188 static const EditCommand kCopyClipboard
[] = {
191 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_4
, GDK_CONTROL_MASK
),
192 kCopyClipboard
, arraysize(kCopyClipboard
));
194 static const EditCommand kCutClipboard
[] = {
197 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_5
, GDK_CONTROL_MASK
),
198 kCutClipboard
, arraysize(kCutClipboard
));
200 static const EditCommand kInsertAtCursor
[] = {
201 { "InsertText", "hello" }
203 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_6
, GDK_CONTROL_MASK
),
204 kInsertAtCursor
, arraysize(kInsertAtCursor
));
206 static const EditCommand kPasteClipboard
[] = {
209 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_7
, GDK_CONTROL_MASK
),
210 kPasteClipboard
, arraysize(kPasteClipboard
));
212 static const EditCommand kSelectAll
[] = {
216 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_8
, GDK_CONTROL_MASK
),
217 kSelectAll
, arraysize(kSelectAll
));
219 static const EditCommand kSetAnchor
[] = {
222 TestKeyBinding(NewNativeWebKeyboardEvent(GDK_9
, GDK_CONTROL_MASK
),
223 kSetAnchor
, arraysize(kSetAnchor
));
226 } // namespace content