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

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

Issue 159586: This CL fixes issue 11480: Support GTK keyboard themes (emacs keybindings).... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 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
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_gtk.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 "chrome/browser/renderer_host/render_widget_host_view_gtk.h" 5 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 #include <gdk/gdk.h> 8 #include <gdk/gdk.h>
9 #include <gdk/gdkkeysyms.h> 9 #include <gdk/gdkkeysyms.h>
10 #include <gdk/gdkx.h> 10 #include <gdk/gdkx.h>
(...skipping 12 matching lines...) Expand all
23 #include "chrome/browser/renderer_host/backing_store.h" 23 #include "chrome/browser/renderer_host/backing_store.h"
24 #include "chrome/browser/renderer_host/render_widget_host.h" 24 #include "chrome/browser/renderer_host/render_widget_host.h"
25 #include "webkit/api/public/gtk/WebInputEventFactory.h" 25 #include "webkit/api/public/gtk/WebInputEventFactory.h"
26 #include "webkit/glue/webcursor_gtk_data.h" 26 #include "webkit/glue/webcursor_gtk_data.h"
27 27
28 static const int kMaxWindowWidth = 4000; 28 static const int kMaxWindowWidth = 4000;
29 static const int kMaxWindowHeight = 4000; 29 static const int kMaxWindowHeight = 4000;
30 30
31 using WebKit::WebInputEventFactory; 31 using WebKit::WebInputEventFactory;
32 32
33 // This class is a conveience wrapper for GtkIMContext. 33 // This class is a convenience class for handling editor key bindings defined
34 // in gtk keyboard theme.
35 // In gtk, only GtkEntry and GtkTextView support customizing editor key bindings
36 // through keyboard theme. And in gtk keyboard theme definition file, each key
37 // binding must be bound to a specific class or object. So existing keyboard
38 // themes only define editor key bindings exactly for GtkEntry and GtkTextView.
39 // Then, the only way for us to intercept editor key bindings defined in
40 // keyboard theme, is to create a GtkEntry or GtkTextView object and call
41 // gtk_bindings_activate_event() against it for the key events. If a key event
42 // matches a predefined key binding, corresponding signal will be emitted.
43 // GtkTextView is used here because it supports more key bindings than GtkEntry,
44 // but in order to minimize the side effect of using a GtkTextView object, a new
45 // class derived from GtkTextView is used, which overrides all signals related
46 // to key bindings, to make sure GtkTextView won't receive them.
47 // Key binding signals will be translated into corresponding webkit editor
48 // commands and send to webkit by calling
49 // RenderWidgetHost::ForwardEditCommand().
50 // See third_party/WebKit/WebCore/editing/EditorCommand.cpp for detailed
51 // definition of webkit editor commands.
52 // See webkit/glue/editor_client_impl.cc for key bindings predefined in our
53 // webkit glue.
54 //
55 // TODO(james.su@gmail.com): Check if current event flow is appropriate, which
56 // sends a key event to renderer(webkit) first, then calls this key bindings
57 // handler if the key event is not handled by renderer. So key bindings
58 // defined in our webkit glue have higher priority.
59 // However, some key bindings defined in our webkit glue may conflict with the
60 // key bindings defined in gtk keyboard theme, for example ctrl-a is
61 // bound to "SelectAll" in our webkit glue. But in gtk Emacs keyboard theme,
62 // it's bound to "MoveToBeginningOfParagraph".
63 // In such case, an Emacs user would prefer Emacs key bindings over our
64 // built-in key bindings.
65 // But it may also cause problem if we call this key bindings handler before
66 // sending key events to renderer, because there is no way to prevent webkit
67 // from interpreting it as a key binding. Then unexpected behavior may occur,
68 // if a key event matches a key binding defined in gtk keyboard theme as well as
69 // a (different) key binding defined in webkit glue.
70 class RenderWidgetHostViewGtkKeyBindings {
Evan Stade 2009/07/30 01:14:56 ok this file is beginning to get absurdly long. Ca
james.su_gmail.com 2009/07/30 06:24:10 I'd like to split this file. Any suggestion to the
71 public:
72 explicit RenderWidgetHostViewGtkKeyBindings(
73 RenderWidgetHostViewGtk* host_view)
74 : host_view_(host_view),
75 handler_(CreateNewHandler()),
76 enabled_(false),
77 handled_(false) {
78 GtkWidget* parent_widget = host_view->native_view();
79 DCHECK(GTK_IS_FIXED(parent_widget));
80 // We need add the |handler_| object into gtk widget hierarchy, so that
81 // gtk_bindings_activate_event() can find correct display and keymaps from
82 // the |handler_| object.
83 gtk_fixed_put(GTK_FIXED(parent_widget), handler_.get(), -1, -1);
84 }
85
86 ~RenderWidgetHostViewGtkKeyBindings() {
87 handler_.Destroy();
88 }
89
90 // Key bindings handler will be disabled when IME is disabled by webkit.
91 void set_enabled(bool enabled) {
92 enabled_ = enabled;
93 }
94
95 // Handles a key event, false will be returned if the key event doesn't
96 // correspond to a predefined key binding.
97 bool Handle(const NativeWebKeyboardEvent& wke) {
98 if (!enabled_ || wke.type == WebKit::WebInputEvent::Char ||
99 !wke.os_event || !wke.os_event->keyval)
100 return false;
101
102 DLOG(INFO) << "Unhandled key "
103 << (wke.os_event->type == GDK_KEY_PRESS ? "press" : "release")
104 << ": keyval=" << wke.os_event->keyval
105 << " state=" << wke.os_event->state;
106
107 handled_ = false;
108
109 // If this key event matches a predefined key binding, corresponding signal
110 // will be emitted.
111 gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), wke.os_event);
112 return handled_;
113 }
114
115 private:
116 struct Handler {
117 GtkTextView parent_object;
118 RenderWidgetHostViewGtkKeyBindings *owner;
119 };
120
121 struct HandlerClass {
122 GtkTextViewClass parent_class;
123 };
124
125 GtkWidget* CreateNewHandler() {
126 Handler* handler =
127 static_cast<Handler*>(g_object_new(HandlerGetType(), NULL));
128
129 handler->owner = this;
130
131 // We don't need to show the |handler| object on screen, so set its size to
132 // zero.
133 gtk_widget_set_size_request(GTK_WIDGET(handler), 0, 0);
134
135 // Prevents it from handling any events by itself.
136 gtk_widget_set_sensitive(GTK_WIDGET(handler), FALSE);
137 gtk_widget_set_events(GTK_WIDGET(handler), 0);
138 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(handler), GTK_CAN_FOCUS);
139
140 #if !GTK_CHECK_VERSION(2, 14, 0)
141 // "move-viewport", "select-all" and "toggle-cursor-visible" have no
142 // corresponding virtual methods. Prior to glib 2.18 (gtk 2.14), there is no
143 // way to override the default class handler of a signal. So we need hook
144 // these signal explicitly, and the default signal handlers of GtkTextView
145 // class will still be called. Hope it won't cause any side effect.
146 g_signal_connect(handler, "move-viewport", G_CALLBACK(MoveViewport), NULL);
147 g_signal_connect(handler, "select-all", G_CALLBACK(SelectAll), NULL);
148 g_signal_connect(handler, "toggle-cursor-visible",
149 G_CALLBACK(ToggleCursorVisible), NULL);
150 #endif
151 return GTK_WIDGET(handler);
152 }
153
154 void ForwardEditCommand(const std::string& name, const std::string& value) {
155 DLOG(INFO) << "ForwardEditCommand:" << name << " value:" << value;
156 host_view_->GetRenderWidgetHost()->ForwardEditCommand(name, value);
Evan Stade 2009/07/30 01:14:56 It looks like ForwardEditCommand does nothing. Is
james.su_gmail.com 2009/07/30 06:24:10 this DLOG is just for debugging, will be removed a
157
158 // A key event is treated as handled only if an editor command is sent to
159 // webkit.
160 handled_ = true;
161 }
162
163 static void HandlerInit(Handler *self) {
164 self->owner = NULL;
165 }
166
167 static void HandlerClassInit(HandlerClass *klass) {
168 GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass);
169
170 // Overrides all virtual methods related to editor key bindings.
171 text_view_class->move_cursor = MoveCursor;
172 text_view_class->set_anchor = SetAnchor;
173 text_view_class->insert_at_cursor = InsertAtCursor;
174 text_view_class->delete_from_cursor = DeleteFromCursor;
175 text_view_class->backspace = BackSpace;
176 text_view_class->cut_clipboard = CutClipboard;
177 text_view_class->copy_clipboard = CopyClipboard;
178 text_view_class->paste_clipboard = PasteClipboard;
179 text_view_class->toggle_overwrite = ToggleOverwrite;
180
181 #if GTK_CHECK_VERSION(2, 14, 0)
182 // "move-viewport", "select-all" and "toggle-cursor-visible" have no
183 // corresponding virtual methods. Since glib 2.18 (gtk 2.14),
184 // g_signal_override_class_handler() is introduced to override a signal
185 // handler.
186 g_signal_override_class_handler("move-viewport",
187 G_TYPE_FROM_CLASS(klass),
188 G_CALLBACK(MoveViewport));
189
190 g_signal_override_class_handler("select-all",
191 G_TYPE_FROM_CLASS(klass),
192 G_CALLBACK(SelectAll));
193
194 g_signal_override_class_handler("toggle-cursor-visible",
195 G_TYPE_FROM_CLASS(klass),
196 G_CALLBACK(ToggleCursorVisible));
197 #endif
198 }
199
200 static GType HandlerGetType() {
201 static volatile gsize type_id_volatile = 0;
202 if (g_once_init_enter(&type_id_volatile)) {
203 GType type_id = g_type_register_static_simple(
204 GTK_TYPE_TEXT_VIEW,
205 g_intern_static_string("RenderWidgetHostViewGtkKeyBindingsHandler"),
206 sizeof(HandlerClass),
207 reinterpret_cast<GClassInitFunc>(HandlerClassInit),
208 sizeof(Handler),
209 reinterpret_cast<GInstanceInitFunc>(HandlerInit),
210 static_cast<GTypeFlags>(0));
211 g_once_init_leave(&type_id_volatile, type_id);
212 }
213 return type_id_volatile;
214 }
215
216 static RenderWidgetHostViewGtkKeyBindings* GetHandlerOwner(
217 GtkTextView* text_view) {
218 Handler* handler = G_TYPE_CHECK_INSTANCE_CAST(
219 text_view, HandlerGetType(), Handler);
220 DCHECK(handler);
221 return handler->owner;
222 }
223
224 static void MoveCursor(GtkTextView* text_view, GtkMovementStep step,
225 gint count, gboolean extend_selection) {
226 if (!count)
227 return;
228
229 std::string command;
230 switch (step) {
231 case GTK_MOVEMENT_LOGICAL_POSITIONS:
232 command = (count > 0 ? "MoveForward" : "MoveBackward");
233 break;
234 case GTK_MOVEMENT_VISUAL_POSITIONS:
235 command = (count > 0 ? "MoveRight" : "MoveLeft");
236 break;
237 case GTK_MOVEMENT_WORDS:
238 command = (count > 0 ? "MoveWordForward" : "MoveWordBackward");
239 break;
240 case GTK_MOVEMENT_DISPLAY_LINES:
241 command = (count > 0 ? "MoveDown" : "MoveUp");
242 break;
243 case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
244 command = (count > 0 ? "MoveToEndOfLine" : "MoveToBeginningOfLine");
245 break;
246 case GTK_MOVEMENT_PARAGRAPH_ENDS:
247 command = (count > 0 ? "MoveToEndOfParagraph" :
248 "MoveToBeginningOfParagraph");
249 break;
250 case GTK_MOVEMENT_PAGES:
251 command = (count > 0 ? "MovePageDown" : "MovePageUp");
252 break;
253 case GTK_MOVEMENT_BUFFER_ENDS:
254 command = (count > 0 ? "MoveToEndOfDocument" :
255 "MoveToBeginningOfDocument");
256 break;
257 default:
258 // GTK_MOVEMENT_PARAGRAPHS and GTK_MOVEMENT_HORIZONTAL_PAGES have
259 // no corresponding editor commands.
260 return;
261 }
262
263 RenderWidgetHostViewGtkKeyBindings* owner = GetHandlerOwner(text_view);
264 if (extend_selection)
265 command.append("AndModifySelection");
266 if (count < 0)
267 count = -count;
268 for (; count > 0; --count)
269 owner->ForwardEditCommand(command, "");
270 }
271
272 static void DeleteFromCursor(GtkTextView* text_view, GtkDeleteType type,
273 gint count) {
274 if (!count)
275 return;
276
277 const char *commands[3] = { NULL, NULL, NULL };
278 switch (type) {
279 case GTK_DELETE_CHARS:
280 commands[0] = (count > 0 ? "Delete" : "DeleteBackward");
281 break;
282 case GTK_DELETE_WORD_ENDS:
283 commands[0] = (count > 0 ? "DeleteWordForward" : "DeleteWordBackward");
284 break;
285 case GTK_DELETE_WORDS:
286 if (count > 0) {
287 commands[0] = "MoveWordForward";
288 commands[1] = "DeleteWordBackward";
289 } else {
290 commands[0] = "MoveWordBackward";
291 commands[1] = "DeleteWordForward";
292 }
293 break;
294 case GTK_DELETE_DISPLAY_LINES:
295 commands[0] = "MoveToBeginningOfLine";
296 commands[1] = "DeleteToEndOfLine";
297 break;
298 case GTK_DELETE_DISPLAY_LINE_ENDS:
299 commands[0] = (count > 0 ? "DeleteToEndOfLine" :
300 "DeleteToBeginningOfLine");
301 break;
302 case GTK_DELETE_PARAGRAPH_ENDS:
303 commands[0] = (count > 0 ? "DeleteToEndOfParagraph" :
304 "DeleteToBeginningOfParagraph");
305 break;
306 case GTK_DELETE_PARAGRAPHS:
307 commands[0] = "MoveToBeginningOfParagraph";
308 commands[1] = "DeleteToEndOfParagraph";
309 break;
310 default:
311 // GTK_DELETE_WHITESPACE has no corresponding editor command.
312 return;
313 }
314
315 RenderWidgetHostViewGtkKeyBindings* owner = GetHandlerOwner(text_view);
316 if (count < 0)
317 count = -count;
318 for (; count > 0; --count) {
319 for (const char* const* p = commands; *p; ++p)
320 owner->ForwardEditCommand(*p, "");
321 }
322 }
323
324 static void InsertAtCursor(GtkTextView* text_view, const gchar* str) {
325 if (str && *str)
326 GetHandlerOwner(text_view)->ForwardEditCommand("InsertText", str);
327 }
328
329 static void BackSpace(GtkTextView* text_view) {
330 GetHandlerOwner(text_view)->ForwardEditCommand("DeleteBackward", "");
331 }
332
333 static void CopyClipboard(GtkTextView* text_view) {
334 GetHandlerOwner(text_view)->ForwardEditCommand("Copy", "");
335 }
336
337 static void CutClipboard(GtkTextView* text_view) {
338 GetHandlerOwner(text_view)->ForwardEditCommand("Cut", "");
339 }
340
341 static void PasteClipboard(GtkTextView* text_view) {
342 GetHandlerOwner(text_view)->ForwardEditCommand("Paste", "");
343 }
344
345 static void SelectAll(GtkTextView* text_view, gboolean select) {
346 if (select)
347 GetHandlerOwner(text_view)->ForwardEditCommand("SelectAll", "");
348 else
349 GetHandlerOwner(text_view)->ForwardEditCommand("Unselect", "");
350 }
351
352 static void SetAnchor(GtkTextView* text_view) {
353 GetHandlerOwner(text_view)->ForwardEditCommand("SetMark", "");
354 }
355
356 static void MoveViewport(GtkTextView* text_view, GtkScrollStep step,
357 gint count) {
358 // Not supported by webkit.
359 }
360
361 static void ToggleOverwrite(GtkTextView* text_view) {
362 // Not supported by webkit.
363 }
364
365 static void ToggleCursorVisible(GtkTextView* text_view) {
366 // Not supported by webkit.
367 }
368
369 RenderWidgetHostViewGtk* host_view_;
370 OwnedWidgetGtk handler_;
371
372 // Indicates if key bindings handler is enabled or not.
373 // It'll only be enabled if IME is enabled by webkit.
374 bool enabled_;
375 bool handled_;
376 };
377
378 // This class is a convenience wrapper for GtkIMContext.
34 class RenderWidgetHostViewGtkIMContext { 379 class RenderWidgetHostViewGtkIMContext {
35 public: 380 public:
36 explicit RenderWidgetHostViewGtkIMContext(RenderWidgetHostViewGtk* host_view) 381 explicit RenderWidgetHostViewGtkIMContext(RenderWidgetHostViewGtk* host_view)
37 : host_view_(host_view), 382 : host_view_(host_view),
38 context_(gtk_im_multicontext_new()), 383 context_(gtk_im_multicontext_new()),
39 context_simple_(gtk_im_context_simple_new()), 384 context_simple_(gtk_im_context_simple_new()),
40 is_focused_(false), 385 is_focused_(false),
41 is_composing_text_(false), 386 is_composing_text_(false),
42 is_enabled_(false), 387 is_enabled_(false),
43 is_in_key_event_handler_(false), 388 is_in_key_event_handler_(false),
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 was_focused_before_grab_(false) { 1194 was_focused_before_grab_(false) {
850 host_->set_view(this); 1195 host_->set_view(this);
851 } 1196 }
852 1197
853 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { 1198 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() {
854 view_.Destroy(); 1199 view_.Destroy();
855 } 1200 }
856 1201
857 void RenderWidgetHostViewGtk::InitAsChild() { 1202 void RenderWidgetHostViewGtk::InitAsChild() {
858 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); 1203 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
1204 key_bindings_handler_.reset(new RenderWidgetHostViewGtkKeyBindings(this));
859 plugin_container_manager_.set_host_widget(view_.get()); 1205 plugin_container_manager_.set_host_widget(view_.get());
860 gtk_widget_show(view_.get()); 1206 gtk_widget_show(view_.get());
861 } 1207 }
862 1208
863 void RenderWidgetHostViewGtk::InitAsPopup( 1209 void RenderWidgetHostViewGtk::InitAsPopup(
864 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { 1210 RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) {
865 parent_host_view_ = parent_host_view; 1211 parent_host_view_ = parent_host_view;
866 parent_ = parent_host_view->GetNativeView(); 1212 parent_ = parent_host_view->GetNativeView();
867 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP); 1213 GtkWidget* popup = gtk_window_new(GTK_WINDOW_POPUP);
868 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); 1214 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this));
1215 key_bindings_handler_.reset(new RenderWidgetHostViewGtkKeyBindings(this));
869 plugin_container_manager_.set_host_widget(view_.get()); 1216 plugin_container_manager_.set_host_widget(view_.get());
870 gtk_container_add(GTK_CONTAINER(popup), view_.get()); 1217 gtk_container_add(GTK_CONTAINER(popup), view_.get());
871 1218
872 // If we are not activatable, we don't want to grab keyboard input, 1219 // If we are not activatable, we don't want to grab keyboard input,
873 // and webkit will manage our destruction. 1220 // and webkit will manage our destruction.
874 if (activatable()) { 1221 if (activatable()) {
875 // Grab all input for the app. If a click lands outside the bounds of the 1222 // Grab all input for the app. If a click lands outside the bounds of the
876 // popup, WebKit will notice and destroy us. Before doing this we need 1223 // popup, WebKit will notice and destroy us. Before doing this we need
877 // to ensure that the the popup is added to the browser's window group, 1224 // to ensure that the the popup is added to the browser's window group,
878 // to allow for the grabs to work correctly. 1225 // to allow for the grabs to work correctly.
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 1356
1010 void RenderWidgetHostViewGtk::SetIsLoading(bool is_loading) { 1357 void RenderWidgetHostViewGtk::SetIsLoading(bool is_loading) {
1011 is_loading_ = is_loading; 1358 is_loading_ = is_loading;
1012 // Only call ShowCurrentCursor() when it will actually change the cursor. 1359 // Only call ShowCurrentCursor() when it will actually change the cursor.
1013 if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR) 1360 if (current_cursor_.GetCursorType() == GDK_LAST_CURSOR)
1014 ShowCurrentCursor(); 1361 ShowCurrentCursor();
1015 } 1362 }
1016 1363
1017 void RenderWidgetHostViewGtk::IMEUpdateStatus(int control, 1364 void RenderWidgetHostViewGtk::IMEUpdateStatus(int control,
1018 const gfx::Rect& caret_rect) { 1365 const gfx::Rect& caret_rect) {
1366 key_bindings_handler_->set_enabled(control != IME_DISABLE);
1019 im_context_->UpdateStatus(control, caret_rect); 1367 im_context_->UpdateStatus(control, caret_rect);
1020 } 1368 }
1021 1369
1022 void RenderWidgetHostViewGtk::DidPaintRect(const gfx::Rect& rect) { 1370 void RenderWidgetHostViewGtk::DidPaintRect(const gfx::Rect& rect) {
1023 if (is_hidden_) 1371 if (is_hidden_)
1024 return; 1372 return;
1025 1373
1026 if (about_to_validate_and_paint_) 1374 if (about_to_validate_and_paint_)
1027 invalid_rect_ = invalid_rect_.Union(rect); 1375 invalid_rect_ = invalid_rect_.Union(rect);
1028 else 1376 else
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 } 1544 }
1197 } 1545 }
1198 1546
1199 void RenderWidgetHostViewGtk::PluginProcessCrashed(base::ProcessId pid) { 1547 void RenderWidgetHostViewGtk::PluginProcessCrashed(base::ProcessId pid) {
1200 for (PluginPidMap::iterator i = plugin_pid_map_.find(pid); 1548 for (PluginPidMap::iterator i = plugin_pid_map_.find(pid);
1201 i != plugin_pid_map_.end() && i->first == pid; ++i) { 1549 i != plugin_pid_map_.end() && i->first == pid; ++i) {
1202 plugin_container_manager_.DestroyPluginContainer(i->second); 1550 plugin_container_manager_.DestroyPluginContainer(i->second);
1203 } 1551 }
1204 plugin_pid_map_.erase(pid); 1552 plugin_pid_map_.erase(pid);
1205 } 1553 }
1554
1555 bool RenderWidgetHostViewGtk::UnhandledKeyboardEvent(
1556 const NativeWebKeyboardEvent& event) {
1557 DCHECK(key_bindings_handler_.get());
1558 return key_bindings_handler_->Handle(event);
1559 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_widget_host_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698