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

Side by Side Diff: chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc

Issue 213283004: linux_aura: Port GtkKeybindingsHandler to Aura. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "content/browser/renderer_host/gtk_key_bindings_handler.h" 5 #include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <X11/Xlib.h>
9 #include <X11/XKBlib.h>
8 10
9 #include <string> 11 #include <string>
10 12
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
13 #include "content/public/browser/native_web_keyboard_event.h" 16 #include "content/public/browser/native_web_keyboard_event.h"
17 #include "ui/base/x/x11_util.h"
18 #include "ui/events/event.h"
14 19
15 namespace content { 20 namespace libgtk2ui {
16 21
17 GtkKeyBindingsHandler::GtkKeyBindingsHandler(GtkWidget* parent_widget) 22 Gtk2KeyBindingsHandler::Gtk2KeyBindingsHandler()
18 : handler_(CreateNewHandler()) { 23 : fake_window_(gtk_offscreen_window_new()),
19 DCHECK(GTK_IS_FIXED(parent_widget)); 24 handler_(CreateNewHandler()),
20 // We need add the |handler_| object into gtk widget hierarchy, so that 25 has_xkb_(false) {
21 // gtk_bindings_activate_event() can find correct display and keymaps from 26 gtk_container_add(GTK_CONTAINER(fake_window_), handler_.get());
22 // the |handler_| object. 27
23 gtk_fixed_put(GTK_FIXED(parent_widget), handler_.get(), -1, -1); 28 int opcode, event, error;
29 int major = XkbMajorVersion;
30 int minor = XkbMinorVersion;
31 if (XkbQueryExtension(gfx::GetXDisplay(), &opcode, &event, &error,
32 &major, &minor))
33 has_xkb_ = true;
24 } 34 }
25 35
26 GtkKeyBindingsHandler::~GtkKeyBindingsHandler() { 36 Gtk2KeyBindingsHandler::~Gtk2KeyBindingsHandler() {
27 handler_.Destroy(); 37 handler_.Destroy();
38 gtk_widget_destroy(fake_window_);
28 } 39 }
29 40
30 bool GtkKeyBindingsHandler::Match(const NativeWebKeyboardEvent& wke, 41 bool Gtk2KeyBindingsHandler::Match(const content::NativeWebKeyboardEvent& wke,
31 EditCommands* edit_commands) { 42 content::EditCommands* edit_commands) {
32 if (wke.type == blink::WebInputEvent::Char || !wke.os_event) 43 if (wke.type == blink::WebInputEvent::Char || !wke.os_event)
33 return false; 44 return false;
34 45
46 GdkEventKey gdk_event;
47 BuildGdkEventKeyFromXEvent(wke.os_event->native_event(), &gdk_event);
48
35 edit_commands_.clear(); 49 edit_commands_.clear();
36 // If this key event matches a predefined key binding, corresponding signal 50 // If this key event matches a predefined key binding, corresponding signal
37 // will be emitted. 51 // will be emitted.
38 gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), &wke.os_event->key); 52 gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), &gdk_event);
39 53
40 bool matched = !edit_commands_.empty(); 54 bool matched = !edit_commands_.empty();
41 if (edit_commands) 55 if (edit_commands)
42 edit_commands->swap(edit_commands_); 56 edit_commands->swap(edit_commands_);
43 return matched; 57 return matched;
44 } 58 }
45 59
46 GtkWidget* GtkKeyBindingsHandler::CreateNewHandler() { 60 GtkWidget* Gtk2KeyBindingsHandler::CreateNewHandler() {
47 Handler* handler = 61 Handler* handler =
48 static_cast<Handler*>(g_object_new(HandlerGetType(), NULL)); 62 static_cast<Handler*>(g_object_new(HandlerGetType(), NULL));
49 63
50 handler->owner = this; 64 handler->owner = this;
51 65
52 // We don't need to show the |handler| object on screen, so set its size to 66 // We don't need to show the |handler| object on screen, so set its size to
53 // zero. 67 // zero.
54 gtk_widget_set_size_request(GTK_WIDGET(handler), 0, 0); 68 gtk_widget_set_size_request(GTK_WIDGET(handler), 0, 0);
55 69
56 // Prevents it from handling any events by itself. 70 // Prevents it from handling any events by itself.
57 gtk_widget_set_sensitive(GTK_WIDGET(handler), FALSE); 71 gtk_widget_set_sensitive(GTK_WIDGET(handler), FALSE);
58 gtk_widget_set_events(GTK_WIDGET(handler), 0); 72 gtk_widget_set_events(GTK_WIDGET(handler), 0);
59 gtk_widget_set_can_focus(GTK_WIDGET(handler), TRUE); 73 gtk_widget_set_can_focus(GTK_WIDGET(handler), TRUE);
60 74
61 return GTK_WIDGET(handler); 75 return GTK_WIDGET(handler);
62 } 76 }
63 77
64 void GtkKeyBindingsHandler::EditCommandMatched( 78 void Gtk2KeyBindingsHandler::EditCommandMatched(
65 const std::string& name, const std::string& value) { 79 const std::string& name, const std::string& value) {
66 edit_commands_.push_back(EditCommand(name, value)); 80 edit_commands_.push_back(content::EditCommand(name, value));
67 } 81 }
68 82
69 void GtkKeyBindingsHandler::HandlerInit(Handler *self) { 83 void Gtk2KeyBindingsHandler::BuildGdkEventKeyFromXEvent(
84 const base::NativeEvent& xevent,
85 GdkEventKey* gdk_event) {
86 GdkKeymap *keymap = gdk_keymap_get_for_display(gdk_display_get_default());
87 GdkModifierType consumed, state;
88
89 gdk_event->type = xevent->xany.type == KeyPress ?
90 GDK_KEY_PRESS : GDK_KEY_RELEASE;
91 gdk_event->time = xevent->xkey.time;
92 gdk_event->state = static_cast<GdkModifierType>(xevent->xkey.state);
93 gdk_event->hardware_keycode = xevent->xkey.keycode;
94
95 if (has_xkb_) {
96 gdk_event->group = XkbGroupForCoreState(xevent->xkey.state);
97 } else {
98 // TODO(erg): I don't understand what this is for. I read through parts of
99 // gdkevent-x11.c. Just calling XkbGroupForCoreState() if we have XKB is
100 // simple enough, but I don't understand X11 input handling enough to know
101 // what this is for, and reading through what GDK does to try to calculate
102 // this was not enlightening.
103 //
104 // Also, does anyone actually have servers that don't support XKB at this
105 // point?
Elliot Glaysher 2014/03/26 21:42:41 piman, do you have any thoughts on what this is su
piman 2014/03/26 23:44:26 My reading of it: GDK installs in the core keymap
106 NOTIMPLEMENTED();
107 gdk_event->group = 0;
108 }
109
110 gdk_event->keyval = GDK_VoidSymbol;
111 gdk_keymap_translate_keyboard_state(
112 keymap,
113 gdk_event->hardware_keycode,
114 static_cast<GdkModifierType>(gdk_event->state),
115 gdk_event->group,
116 &gdk_event->keyval,
117 NULL, NULL, &consumed);
118
119 state = static_cast<GdkModifierType>(gdk_event->state & ~consumed);
120 gdk_keymap_add_virtual_modifiers(keymap, &state);
121 gdk_event->state |= state;
122 }
123
124 void Gtk2KeyBindingsHandler::HandlerInit(Handler *self) {
70 self->owner = NULL; 125 self->owner = NULL;
71 } 126 }
72 127
73 void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass *klass) { 128 void Gtk2KeyBindingsHandler::HandlerClassInit(HandlerClass *klass) {
74 GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass); 129 GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass);
75 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass); 130 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
76 131
77 // Overrides all virtual methods related to editor key bindings. 132 // Overrides all virtual methods related to editor key bindings.
78 text_view_class->backspace = BackSpace; 133 text_view_class->backspace = BackSpace;
79 text_view_class->copy_clipboard = CopyClipboard; 134 text_view_class->copy_clipboard = CopyClipboard;
80 text_view_class->cut_clipboard = CutClipboard; 135 text_view_class->cut_clipboard = CutClipboard;
81 text_view_class->delete_from_cursor = DeleteFromCursor; 136 text_view_class->delete_from_cursor = DeleteFromCursor;
82 text_view_class->insert_at_cursor = InsertAtCursor; 137 text_view_class->insert_at_cursor = InsertAtCursor;
83 text_view_class->move_cursor = MoveCursor; 138 text_view_class->move_cursor = MoveCursor;
(...skipping 16 matching lines...) Expand all
100 155
101 g_signal_override_class_handler("select-all", 156 g_signal_override_class_handler("select-all",
102 G_TYPE_FROM_CLASS(klass), 157 G_TYPE_FROM_CLASS(klass),
103 G_CALLBACK(SelectAll)); 158 G_CALLBACK(SelectAll));
104 159
105 g_signal_override_class_handler("toggle-cursor-visible", 160 g_signal_override_class_handler("toggle-cursor-visible",
106 G_TYPE_FROM_CLASS(klass), 161 G_TYPE_FROM_CLASS(klass),
107 G_CALLBACK(ToggleCursorVisible)); 162 G_CALLBACK(ToggleCursorVisible));
108 } 163 }
109 164
110 GType GtkKeyBindingsHandler::HandlerGetType() { 165 GType Gtk2KeyBindingsHandler::HandlerGetType() {
111 static volatile gsize type_id_volatile = 0; 166 static volatile gsize type_id_volatile = 0;
112 if (g_once_init_enter(&type_id_volatile)) { 167 if (g_once_init_enter(&type_id_volatile)) {
113 GType type_id = g_type_register_static_simple( 168 GType type_id = g_type_register_static_simple(
114 GTK_TYPE_TEXT_VIEW, 169 GTK_TYPE_TEXT_VIEW,
115 g_intern_static_string("GtkKeyBindingsHandler"), 170 g_intern_static_string("Gtk2KeyBindingsHandler"),
116 sizeof(HandlerClass), 171 sizeof(HandlerClass),
117 reinterpret_cast<GClassInitFunc>(HandlerClassInit), 172 reinterpret_cast<GClassInitFunc>(HandlerClassInit),
118 sizeof(Handler), 173 sizeof(Handler),
119 reinterpret_cast<GInstanceInitFunc>(HandlerInit), 174 reinterpret_cast<GInstanceInitFunc>(HandlerInit),
120 static_cast<GTypeFlags>(0)); 175 static_cast<GTypeFlags>(0));
121 g_once_init_leave(&type_id_volatile, type_id); 176 g_once_init_leave(&type_id_volatile, type_id);
122 } 177 }
123 return type_id_volatile; 178 return type_id_volatile;
124 } 179 }
125 180
126 GtkKeyBindingsHandler* GtkKeyBindingsHandler::GetHandlerOwner( 181 Gtk2KeyBindingsHandler* Gtk2KeyBindingsHandler::GetHandlerOwner(
127 GtkTextView* text_view) { 182 GtkTextView* text_view) {
128 Handler* handler = G_TYPE_CHECK_INSTANCE_CAST( 183 Handler* handler = G_TYPE_CHECK_INSTANCE_CAST(
129 text_view, HandlerGetType(), Handler); 184 text_view, HandlerGetType(), Handler);
130 DCHECK(handler); 185 DCHECK(handler);
131 return handler->owner; 186 return handler->owner;
132 } 187 }
133 188
134 void GtkKeyBindingsHandler::BackSpace(GtkTextView* text_view) { 189 void Gtk2KeyBindingsHandler::BackSpace(GtkTextView* text_view) {
135 GetHandlerOwner(text_view) 190 GetHandlerOwner(text_view)
136 ->EditCommandMatched("DeleteBackward", std::string()); 191 ->EditCommandMatched("DeleteBackward", std::string());
137 } 192 }
138 193
139 void GtkKeyBindingsHandler::CopyClipboard(GtkTextView* text_view) { 194 void Gtk2KeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
140 GetHandlerOwner(text_view)->EditCommandMatched("Copy", std::string()); 195 GetHandlerOwner(text_view)->EditCommandMatched("Copy", std::string());
141 } 196 }
142 197
143 void GtkKeyBindingsHandler::CutClipboard(GtkTextView* text_view) { 198 void Gtk2KeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
144 GetHandlerOwner(text_view)->EditCommandMatched("Cut", std::string()); 199 GetHandlerOwner(text_view)->EditCommandMatched("Cut", std::string());
145 } 200 }
146 201
147 void GtkKeyBindingsHandler::DeleteFromCursor( 202 void Gtk2KeyBindingsHandler::DeleteFromCursor(
148 GtkTextView* text_view, GtkDeleteType type, gint count) { 203 GtkTextView* text_view, GtkDeleteType type, gint count) {
149 if (!count) 204 if (!count)
150 return; 205 return;
151 206
152 const char *commands[3] = { NULL, NULL, NULL }; 207 const char *commands[3] = { NULL, NULL, NULL };
153 switch (type) { 208 switch (type) {
154 case GTK_DELETE_CHARS: 209 case GTK_DELETE_CHARS:
155 commands[0] = (count > 0 ? "DeleteForward" : "DeleteBackward"); 210 commands[0] = (count > 0 ? "DeleteForward" : "DeleteBackward");
156 break; 211 break;
157 case GTK_DELETE_WORD_ENDS: 212 case GTK_DELETE_WORD_ENDS:
(...skipping 22 matching lines...) Expand all
180 break; 235 break;
181 case GTK_DELETE_PARAGRAPHS: 236 case GTK_DELETE_PARAGRAPHS:
182 commands[0] = "MoveToBeginningOfParagraph"; 237 commands[0] = "MoveToBeginningOfParagraph";
183 commands[1] = "DeleteToEndOfParagraph"; 238 commands[1] = "DeleteToEndOfParagraph";
184 break; 239 break;
185 default: 240 default:
186 // GTK_DELETE_WHITESPACE has no corresponding editor command. 241 // GTK_DELETE_WHITESPACE has no corresponding editor command.
187 return; 242 return;
188 } 243 }
189 244
190 GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view); 245 Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view);
191 if (count < 0) 246 if (count < 0)
192 count = -count; 247 count = -count;
193 for (; count > 0; --count) { 248 for (; count > 0; --count) {
194 for (const char* const* p = commands; *p; ++p) 249 for (const char* const* p = commands; *p; ++p)
195 owner->EditCommandMatched(*p, std::string()); 250 owner->EditCommandMatched(*p, std::string());
196 } 251 }
197 } 252 }
198 253
199 void GtkKeyBindingsHandler::InsertAtCursor(GtkTextView* text_view, 254 void Gtk2KeyBindingsHandler::InsertAtCursor(GtkTextView* text_view,
200 const gchar* str) { 255 const gchar* str) {
201 if (str && *str) 256 if (str && *str)
202 GetHandlerOwner(text_view)->EditCommandMatched("InsertText", str); 257 GetHandlerOwner(text_view)->EditCommandMatched("InsertText", str);
203 } 258 }
204 259
205 void GtkKeyBindingsHandler::MoveCursor( 260 void Gtk2KeyBindingsHandler::MoveCursor(
206 GtkTextView* text_view, GtkMovementStep step, gint count, 261 GtkTextView* text_view, GtkMovementStep step, gint count,
207 gboolean extend_selection) { 262 gboolean extend_selection) {
208 if (!count) 263 if (!count)
209 return; 264 return;
210 265
211 std::string command; 266 std::string command;
212 switch (step) { 267 switch (step) {
213 case GTK_MOVEMENT_LOGICAL_POSITIONS: 268 case GTK_MOVEMENT_LOGICAL_POSITIONS:
214 command = (count > 0 ? "MoveForward" : "MoveBackward"); 269 command = (count > 0 ? "MoveForward" : "MoveBackward");
215 break; 270 break;
(...skipping 19 matching lines...) Expand all
235 case GTK_MOVEMENT_BUFFER_ENDS: 290 case GTK_MOVEMENT_BUFFER_ENDS:
236 command = (count > 0 ? "MoveToEndOfDocument" : 291 command = (count > 0 ? "MoveToEndOfDocument" :
237 "MoveToBeginningOfDocument"); 292 "MoveToBeginningOfDocument");
238 break; 293 break;
239 default: 294 default:
240 // GTK_MOVEMENT_PARAGRAPHS and GTK_MOVEMENT_HORIZONTAL_PAGES have 295 // GTK_MOVEMENT_PARAGRAPHS and GTK_MOVEMENT_HORIZONTAL_PAGES have
241 // no corresponding editor commands. 296 // no corresponding editor commands.
242 return; 297 return;
243 } 298 }
244 299
245 GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view); 300 Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view);
246 if (extend_selection) 301 if (extend_selection)
247 command.append("AndModifySelection"); 302 command.append("AndModifySelection");
248 if (count < 0) 303 if (count < 0)
249 count = -count; 304 count = -count;
250 for (; count > 0; --count) 305 for (; count > 0; --count)
251 owner->EditCommandMatched(command, std::string()); 306 owner->EditCommandMatched(command, std::string());
252 } 307 }
253 308
254 void GtkKeyBindingsHandler::MoveViewport( 309 void Gtk2KeyBindingsHandler::MoveViewport(
255 GtkTextView* text_view, GtkScrollStep step, gint count) { 310 GtkTextView* text_view, GtkScrollStep step, gint count) {
256 // Not supported by webkit. 311 // Not supported by webkit.
257 } 312 }
258 313
259 void GtkKeyBindingsHandler::PasteClipboard(GtkTextView* text_view) { 314 void Gtk2KeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
260 GetHandlerOwner(text_view)->EditCommandMatched("Paste", std::string()); 315 GetHandlerOwner(text_view)->EditCommandMatched("Paste", std::string());
261 } 316 }
262 317
263 void GtkKeyBindingsHandler::SelectAll(GtkTextView* text_view, gboolean select) { 318 void Gtk2KeyBindingsHandler::SelectAll(GtkTextView* text_view,
319 gboolean select) {
264 if (select) 320 if (select)
265 GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", std::string()); 321 GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", std::string());
266 else 322 else
267 GetHandlerOwner(text_view)->EditCommandMatched("Unselect", std::string()); 323 GetHandlerOwner(text_view)->EditCommandMatched("Unselect", std::string());
268 } 324 }
269 325
270 void GtkKeyBindingsHandler::SetAnchor(GtkTextView* text_view) { 326 void Gtk2KeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
271 GetHandlerOwner(text_view)->EditCommandMatched("SetMark", std::string()); 327 GetHandlerOwner(text_view)->EditCommandMatched("SetMark", std::string());
272 } 328 }
273 329
274 void GtkKeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) { 330 void Gtk2KeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
275 // Not supported by webkit. 331 // Not supported by webkit.
276 } 332 }
277 333
278 void GtkKeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) { 334 void Gtk2KeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) {
279 // Not supported by webkit. 335 // Not supported by webkit.
280 } 336 }
281 337
282 gboolean GtkKeyBindingsHandler::ShowHelp(GtkWidget* widget, 338 gboolean Gtk2KeyBindingsHandler::ShowHelp(GtkWidget* widget,
283 GtkWidgetHelpType arg1) { 339 GtkWidgetHelpType arg1) {
284 // Just for disabling the default handler. 340 // Just for disabling the default handler.
285 return FALSE; 341 return FALSE;
286 } 342 }
287 343
288 void GtkKeyBindingsHandler::MoveFocus(GtkWidget* widget, 344 void Gtk2KeyBindingsHandler::MoveFocus(GtkWidget* widget,
289 GtkDirectionType arg1) { 345 GtkDirectionType arg1) {
290 // Just for disabling the default handler. 346 // Just for disabling the default handler.
291 } 347 }
292 348
293 } // namespace content 349 } // namespace libgtk2ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698