Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: chrome/browser/renderer_host/gtk_key_bindings_handler.cc

Issue 7669040: content: Move render_widget_host_view_gtk to content/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: chromeos fix. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/renderer_host/gtk_key_bindings_handler.h"
6
7 #include <gdk/gdkkeysyms.h>
8
9 #include <string>
10
11 #include "base/logging.h"
12 #include "base/string_util.h"
13 #include "content/common/native_web_keyboard_event.h"
14
15 GtkKeyBindingsHandler::GtkKeyBindingsHandler(GtkWidget* parent_widget)
16 : handler_(CreateNewHandler()) {
17 DCHECK(GTK_IS_FIXED(parent_widget));
18 // We need add the |handler_| object into gtk widget hierarchy, so that
19 // gtk_bindings_activate_event() can find correct display and keymaps from
20 // the |handler_| object.
21 gtk_fixed_put(GTK_FIXED(parent_widget), handler_.get(), -1, -1);
22 }
23
24 GtkKeyBindingsHandler::~GtkKeyBindingsHandler() {
25 handler_.Destroy();
26 }
27
28 bool GtkKeyBindingsHandler::Match(const NativeWebKeyboardEvent& wke,
29 EditCommands* edit_commands) {
30 if (wke.type == WebKit::WebInputEvent::Char || !wke.os_event)
31 return false;
32
33 edit_commands_.clear();
34 // If this key event matches a predefined key binding, corresponding signal
35 // will be emitted.
36 gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), wke.os_event);
37
38 bool matched = !edit_commands_.empty();
39 if (edit_commands)
40 edit_commands->swap(edit_commands_);
41 return matched;
42 }
43
44 GtkWidget* GtkKeyBindingsHandler::CreateNewHandler() {
45 Handler* handler =
46 static_cast<Handler*>(g_object_new(HandlerGetType(), NULL));
47
48 handler->owner = this;
49
50 // We don't need to show the |handler| object on screen, so set its size to
51 // zero.
52 gtk_widget_set_size_request(GTK_WIDGET(handler), 0, 0);
53
54 // Prevents it from handling any events by itself.
55 gtk_widget_set_sensitive(GTK_WIDGET(handler), FALSE);
56 gtk_widget_set_events(GTK_WIDGET(handler), 0);
57 gtk_widget_set_can_focus(GTK_WIDGET(handler), TRUE);
58
59 #if !GTK_CHECK_VERSION(2, 14, 0)
60 // "move-focus", "move-viewport", "select-all" and "toggle-cursor-visible"
61 // have no corresponding virtual methods. Prior to glib 2.18 (gtk 2.14),
62 // there is no way to override the default class handler of a signal.
63 // So we need hook these signal explicitly.
64 g_signal_connect(handler, "move-focus", G_CALLBACK(MoveFocus), NULL);
65 g_signal_connect(handler, "move-viewport", G_CALLBACK(MoveViewport), NULL);
66 g_signal_connect(handler, "select-all", G_CALLBACK(SelectAll), NULL);
67 g_signal_connect(handler, "toggle-cursor-visible",
68 G_CALLBACK(ToggleCursorVisible), NULL);
69 #endif
70 return GTK_WIDGET(handler);
71 }
72
73 void GtkKeyBindingsHandler::EditCommandMatched(
74 const std::string& name, const std::string& value) {
75 edit_commands_.push_back(EditCommand(name, value));
76 }
77
78 void GtkKeyBindingsHandler::HandlerInit(Handler *self) {
79 self->owner = NULL;
80 }
81
82 void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass *klass) {
83 GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass);
84 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
85
86 // Overrides all virtual methods related to editor key bindings.
87 text_view_class->backspace = BackSpace;
88 text_view_class->copy_clipboard = CopyClipboard;
89 text_view_class->cut_clipboard = CutClipboard;
90 text_view_class->delete_from_cursor = DeleteFromCursor;
91 text_view_class->insert_at_cursor = InsertAtCursor;
92 text_view_class->move_cursor = MoveCursor;
93 text_view_class->paste_clipboard = PasteClipboard;
94 text_view_class->set_anchor = SetAnchor;
95 text_view_class->toggle_overwrite = ToggleOverwrite;
96 widget_class->show_help = ShowHelp;
97
98 #if GTK_CHECK_VERSION(2, 14, 0)
99 // "move-focus", "move-viewport", "select-all" and "toggle-cursor-visible"
100 // have no corresponding virtual methods. Since glib 2.18 (gtk 2.14),
101 // g_signal_override_class_handler() is introduced to override a signal
102 // handler.
103 g_signal_override_class_handler("move-focus",
104 G_TYPE_FROM_CLASS(klass),
105 G_CALLBACK(MoveFocus));
106
107 g_signal_override_class_handler("move-viewport",
108 G_TYPE_FROM_CLASS(klass),
109 G_CALLBACK(MoveViewport));
110
111 g_signal_override_class_handler("select-all",
112 G_TYPE_FROM_CLASS(klass),
113 G_CALLBACK(SelectAll));
114
115 g_signal_override_class_handler("toggle-cursor-visible",
116 G_TYPE_FROM_CLASS(klass),
117 G_CALLBACK(ToggleCursorVisible));
118 #endif
119 }
120
121 GType GtkKeyBindingsHandler::HandlerGetType() {
122 static volatile gsize type_id_volatile = 0;
123 if (g_once_init_enter(&type_id_volatile)) {
124 GType type_id = g_type_register_static_simple(
125 GTK_TYPE_TEXT_VIEW,
126 g_intern_static_string("GtkKeyBindingsHandler"),
127 sizeof(HandlerClass),
128 reinterpret_cast<GClassInitFunc>(HandlerClassInit),
129 sizeof(Handler),
130 reinterpret_cast<GInstanceInitFunc>(HandlerInit),
131 static_cast<GTypeFlags>(0));
132 g_once_init_leave(&type_id_volatile, type_id);
133 }
134 return type_id_volatile;
135 }
136
137 GtkKeyBindingsHandler* GtkKeyBindingsHandler::GetHandlerOwner(
138 GtkTextView* text_view) {
139 Handler* handler = G_TYPE_CHECK_INSTANCE_CAST(
140 text_view, HandlerGetType(), Handler);
141 DCHECK(handler);
142 return handler->owner;
143 }
144
145 void GtkKeyBindingsHandler::BackSpace(GtkTextView* text_view) {
146 GetHandlerOwner(text_view)->EditCommandMatched("DeleteBackward", "");
147 }
148
149 void GtkKeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
150 GetHandlerOwner(text_view)->EditCommandMatched("Copy", "");
151 }
152
153 void GtkKeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
154 GetHandlerOwner(text_view)->EditCommandMatched("Cut", "");
155 }
156
157 void GtkKeyBindingsHandler::DeleteFromCursor(
158 GtkTextView* text_view, GtkDeleteType type, gint count) {
159 if (!count)
160 return;
161
162 const char *commands[3] = { NULL, NULL, NULL };
163 switch (type) {
164 case GTK_DELETE_CHARS:
165 commands[0] = (count > 0 ? "DeleteForward" : "DeleteBackward");
166 break;
167 case GTK_DELETE_WORD_ENDS:
168 commands[0] = (count > 0 ? "DeleteWordForward" : "DeleteWordBackward");
169 break;
170 case GTK_DELETE_WORDS:
171 if (count > 0) {
172 commands[0] = "MoveWordForward";
173 commands[1] = "DeleteWordBackward";
174 } else {
175 commands[0] = "MoveWordBackward";
176 commands[1] = "DeleteWordForward";
177 }
178 break;
179 case GTK_DELETE_DISPLAY_LINES:
180 commands[0] = "MoveToBeginningOfLine";
181 commands[1] = "DeleteToEndOfLine";
182 break;
183 case GTK_DELETE_DISPLAY_LINE_ENDS:
184 commands[0] = (count > 0 ? "DeleteToEndOfLine" :
185 "DeleteToBeginningOfLine");
186 break;
187 case GTK_DELETE_PARAGRAPH_ENDS:
188 commands[0] = (count > 0 ? "DeleteToEndOfParagraph" :
189 "DeleteToBeginningOfParagraph");
190 break;
191 case GTK_DELETE_PARAGRAPHS:
192 commands[0] = "MoveToBeginningOfParagraph";
193 commands[1] = "DeleteToEndOfParagraph";
194 break;
195 default:
196 // GTK_DELETE_WHITESPACE has no corresponding editor command.
197 return;
198 }
199
200 GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
201 if (count < 0)
202 count = -count;
203 for (; count > 0; --count) {
204 for (const char* const* p = commands; *p; ++p)
205 owner->EditCommandMatched(*p, "");
206 }
207 }
208
209 void GtkKeyBindingsHandler::InsertAtCursor(GtkTextView* text_view,
210 const gchar* str) {
211 if (str && *str)
212 GetHandlerOwner(text_view)->EditCommandMatched("InsertText", str);
213 }
214
215 void GtkKeyBindingsHandler::MoveCursor(
216 GtkTextView* text_view, GtkMovementStep step, gint count,
217 gboolean extend_selection) {
218 if (!count)
219 return;
220
221 std::string command;
222 switch (step) {
223 case GTK_MOVEMENT_LOGICAL_POSITIONS:
224 command = (count > 0 ? "MoveForward" : "MoveBackward");
225 break;
226 case GTK_MOVEMENT_VISUAL_POSITIONS:
227 command = (count > 0 ? "MoveRight" : "MoveLeft");
228 break;
229 case GTK_MOVEMENT_WORDS:
230 command = (count > 0 ? "MoveWordForward" : "MoveWordBackward");
231 break;
232 case GTK_MOVEMENT_DISPLAY_LINES:
233 command = (count > 0 ? "MoveDown" : "MoveUp");
234 break;
235 case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
236 command = (count > 0 ? "MoveToEndOfLine" : "MoveToBeginningOfLine");
237 break;
238 case GTK_MOVEMENT_PARAGRAPH_ENDS:
239 command = (count > 0 ? "MoveToEndOfParagraph" :
240 "MoveToBeginningOfParagraph");
241 break;
242 case GTK_MOVEMENT_PAGES:
243 command = (count > 0 ? "MovePageDown" : "MovePageUp");
244 break;
245 case GTK_MOVEMENT_BUFFER_ENDS:
246 command = (count > 0 ? "MoveToEndOfDocument" :
247 "MoveToBeginningOfDocument");
248 break;
249 default:
250 // GTK_MOVEMENT_PARAGRAPHS and GTK_MOVEMENT_HORIZONTAL_PAGES have
251 // no corresponding editor commands.
252 return;
253 }
254
255 GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
256 if (extend_selection)
257 command.append("AndModifySelection");
258 if (count < 0)
259 count = -count;
260 for (; count > 0; --count)
261 owner->EditCommandMatched(command, "");
262 }
263
264 void GtkKeyBindingsHandler::MoveViewport(
265 GtkTextView* text_view, GtkScrollStep step, gint count) {
266 // Not supported by webkit.
267 #if !GTK_CHECK_VERSION(2, 14, 0)
268 // Before gtk 2.14.0, there is no way to override a non-virtual default signal
269 // handler, so we need stop the signal emission explicitly to prevent the
270 // default handler from being executed.
271 g_signal_stop_emission_by_name(text_view, "move-viewport");
272 #endif
273 }
274
275 void GtkKeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
276 GetHandlerOwner(text_view)->EditCommandMatched("Paste", "");
277 }
278
279 void GtkKeyBindingsHandler::SelectAll(GtkTextView* text_view, gboolean select) {
280 if (select)
281 GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", "");
282 else
283 GetHandlerOwner(text_view)->EditCommandMatched("Unselect", "");
284 #if !GTK_CHECK_VERSION(2, 14, 0)
285 // Before gtk 2.14.0, there is no way to override a non-virtual default signal
286 // handler, so we need stop the signal emission explicitly to prevent the
287 // default handler from being executed.
288 g_signal_stop_emission_by_name(text_view, "select-all");
289 #endif
290 }
291
292 void GtkKeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
293 GetHandlerOwner(text_view)->EditCommandMatched("SetMark", "");
294 }
295
296 void GtkKeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
297 // Not supported by webkit.
298 #if !GTK_CHECK_VERSION(2, 14, 0)
299 // Before gtk 2.14.0, there is no way to override a non-virtual default signal
300 // handler, so we need stop the signal emission explicitly to prevent the
301 // default handler from being executed.
302 g_signal_stop_emission_by_name(text_view, "toggle-cursor-visible");
303 #endif
304 }
305
306 void GtkKeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) {
307 // Not supported by webkit.
308 }
309
310 gboolean GtkKeyBindingsHandler::ShowHelp(GtkWidget* widget,
311 GtkWidgetHelpType arg1) {
312 // Just for disabling the default handler.
313 return FALSE;
314 }
315
316 void GtkKeyBindingsHandler::MoveFocus(GtkWidget* widget,
317 GtkDirectionType arg1) {
318 // Just for disabling the default handler.
319 #if !GTK_CHECK_VERSION(2, 14, 0)
320 // Before gtk 2.14.0, there is no way to override a non-virtual default signal
321 // handler, so we need stop the signal emission explicitly to prevent the
322 // default handler from being executed.
323 g_signal_stop_emission_by_name(widget, "move-focus");
324 #endif
325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698