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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
diff --git a/content/browser/renderer_host/gtk_key_bindings_handler.cc b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
similarity index 63%
copy from content/browser/renderer_host/gtk_key_bindings_handler.cc
copy to chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
index 3830364a0e8ff1b979306e06f5f6341d0fb58396..88a6da3a734a8fc8c2fe6c18408022f8a767a8f2 100644
--- a/content/browser/renderer_host/gtk_key_bindings_handler.cc
+++ b/chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.cc
@@ -2,40 +2,54 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/renderer_host/gtk_key_bindings_handler.h"
+#include "chrome/browser/ui/libgtk2ui/gtk2_key_bindings_handler.h"
#include <gdk/gdkkeysyms.h>
+#include <X11/Xlib.h>
+#include <X11/XKBlib.h>
#include <string>
#include "base/logging.h"
#include "base/strings/string_util.h"
+#include "chrome/browser/ui/libgtk2ui/gtk2_util.h"
#include "content/public/browser/native_web_keyboard_event.h"
-
-namespace content {
-
-GtkKeyBindingsHandler::GtkKeyBindingsHandler(GtkWidget* parent_widget)
- : handler_(CreateNewHandler()) {
- DCHECK(GTK_IS_FIXED(parent_widget));
- // We need add the |handler_| object into gtk widget hierarchy, so that
- // gtk_bindings_activate_event() can find correct display and keymaps from
- // the |handler_| object.
- gtk_fixed_put(GTK_FIXED(parent_widget), handler_.get(), -1, -1);
+#include "ui/base/x/x11_util.h"
+#include "ui/events/event.h"
+
+namespace libgtk2ui {
+
+Gtk2KeyBindingsHandler::Gtk2KeyBindingsHandler()
+ : fake_window_(gtk_offscreen_window_new()),
+ handler_(CreateNewHandler()),
+ has_xkb_(false) {
+ gtk_container_add(GTK_CONTAINER(fake_window_), handler_.get());
+
+ int opcode, event, error;
+ int major = XkbMajorVersion;
+ int minor = XkbMinorVersion;
+ if (XkbQueryExtension(gfx::GetXDisplay(), &opcode, &event, &error,
+ &major, &minor))
+ has_xkb_ = true;
}
-GtkKeyBindingsHandler::~GtkKeyBindingsHandler() {
+Gtk2KeyBindingsHandler::~Gtk2KeyBindingsHandler() {
handler_.Destroy();
+ gtk_widget_destroy(fake_window_);
}
-bool GtkKeyBindingsHandler::Match(const NativeWebKeyboardEvent& wke,
- EditCommands* edit_commands) {
+bool Gtk2KeyBindingsHandler::Match(const content::NativeWebKeyboardEvent& wke,
+ content::EditCommands* edit_commands) {
if (wke.type == blink::WebInputEvent::Char || !wke.os_event)
return false;
+ GdkEventKey gdk_event;
+ BuildGdkEventKeyFromXEvent(wke.os_event->native_event(), &gdk_event);
+
edit_commands_.clear();
// If this key event matches a predefined key binding, corresponding signal
// will be emitted.
- gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), &wke.os_event->key);
+ gtk_bindings_activate_event(GTK_OBJECT(handler_.get()), &gdk_event);
bool matched = !edit_commands_.empty();
if (edit_commands)
@@ -43,7 +57,7 @@ bool GtkKeyBindingsHandler::Match(const NativeWebKeyboardEvent& wke,
return matched;
}
-GtkWidget* GtkKeyBindingsHandler::CreateNewHandler() {
+GtkWidget* Gtk2KeyBindingsHandler::CreateNewHandler() {
Handler* handler =
static_cast<Handler*>(g_object_new(HandlerGetType(), NULL));
@@ -61,16 +75,57 @@ GtkWidget* GtkKeyBindingsHandler::CreateNewHandler() {
return GTK_WIDGET(handler);
}
-void GtkKeyBindingsHandler::EditCommandMatched(
+void Gtk2KeyBindingsHandler::EditCommandMatched(
const std::string& name, const std::string& value) {
- edit_commands_.push_back(EditCommand(name, value));
+ edit_commands_.push_back(content::EditCommand(name, value));
+}
+
+void Gtk2KeyBindingsHandler::BuildGdkEventKeyFromXEvent(
+ const base::NativeEvent& xevent,
+ GdkEventKey* gdk_event) {
+ GdkKeymap *keymap = gdk_keymap_get_for_display(gdk_display_get_default());
+ GdkModifierType consumed, state;
+
+ gdk_event->type = xevent->xany.type == KeyPress ?
+ GDK_KEY_PRESS : GDK_KEY_RELEASE;
+ gdk_event->time = xevent->xkey.time;
+ gdk_event->state = static_cast<GdkModifierType>(xevent->xkey.state);
+ gdk_event->hardware_keycode = xevent->xkey.keycode;
+
+ if (has_xkb_) {
+ gdk_event->group = XkbGroupForCoreState(xevent->xkey.state);
+ } else {
+ // TODO(erg): I don't understand what this is for. I read through parts of
+ // gdkevent-x11.c. Just calling XkbGroupForCoreState() if we have XKB is
+ // simple enough, but I don't understand X11 input handling enough to know
+ // what this is for, and reading through what GDK does to try to calculate
+ // this was not enlightening.
+ //
+ // Also, does anyone actually have servers that don't support XKB at this
+ // 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
+ NOTIMPLEMENTED();
+ gdk_event->group = 0;
+ }
+
+ gdk_event->keyval = GDK_VoidSymbol;
+ gdk_keymap_translate_keyboard_state(
+ keymap,
+ gdk_event->hardware_keycode,
+ static_cast<GdkModifierType>(gdk_event->state),
+ gdk_event->group,
+ &gdk_event->keyval,
+ NULL, NULL, &consumed);
+
+ state = static_cast<GdkModifierType>(gdk_event->state & ~consumed);
+ gdk_keymap_add_virtual_modifiers(keymap, &state);
+ gdk_event->state |= state;
}
-void GtkKeyBindingsHandler::HandlerInit(Handler *self) {
+void Gtk2KeyBindingsHandler::HandlerInit(Handler *self) {
self->owner = NULL;
}
-void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass *klass) {
+void Gtk2KeyBindingsHandler::HandlerClassInit(HandlerClass *klass) {
GtkTextViewClass* text_view_class = GTK_TEXT_VIEW_CLASS(klass);
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
@@ -107,12 +162,12 @@ void GtkKeyBindingsHandler::HandlerClassInit(HandlerClass *klass) {
G_CALLBACK(ToggleCursorVisible));
}
-GType GtkKeyBindingsHandler::HandlerGetType() {
+GType Gtk2KeyBindingsHandler::HandlerGetType() {
static volatile gsize type_id_volatile = 0;
if (g_once_init_enter(&type_id_volatile)) {
GType type_id = g_type_register_static_simple(
GTK_TYPE_TEXT_VIEW,
- g_intern_static_string("GtkKeyBindingsHandler"),
+ g_intern_static_string("Gtk2KeyBindingsHandler"),
sizeof(HandlerClass),
reinterpret_cast<GClassInitFunc>(HandlerClassInit),
sizeof(Handler),
@@ -123,7 +178,7 @@ GType GtkKeyBindingsHandler::HandlerGetType() {
return type_id_volatile;
}
-GtkKeyBindingsHandler* GtkKeyBindingsHandler::GetHandlerOwner(
+Gtk2KeyBindingsHandler* Gtk2KeyBindingsHandler::GetHandlerOwner(
GtkTextView* text_view) {
Handler* handler = G_TYPE_CHECK_INSTANCE_CAST(
text_view, HandlerGetType(), Handler);
@@ -131,20 +186,20 @@ GtkKeyBindingsHandler* GtkKeyBindingsHandler::GetHandlerOwner(
return handler->owner;
}
-void GtkKeyBindingsHandler::BackSpace(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::BackSpace(GtkTextView* text_view) {
GetHandlerOwner(text_view)
->EditCommandMatched("DeleteBackward", std::string());
}
-void GtkKeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::CopyClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched("Copy", std::string());
}
-void GtkKeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::CutClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched("Cut", std::string());
}
-void GtkKeyBindingsHandler::DeleteFromCursor(
+void Gtk2KeyBindingsHandler::DeleteFromCursor(
GtkTextView* text_view, GtkDeleteType type, gint count) {
if (!count)
return;
@@ -187,7 +242,7 @@ void GtkKeyBindingsHandler::DeleteFromCursor(
return;
}
- GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
+ Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view);
if (count < 0)
count = -count;
for (; count > 0; --count) {
@@ -196,13 +251,13 @@ void GtkKeyBindingsHandler::DeleteFromCursor(
}
}
-void GtkKeyBindingsHandler::InsertAtCursor(GtkTextView* text_view,
- const gchar* str) {
+void Gtk2KeyBindingsHandler::InsertAtCursor(GtkTextView* text_view,
+ const gchar* str) {
if (str && *str)
GetHandlerOwner(text_view)->EditCommandMatched("InsertText", str);
}
-void GtkKeyBindingsHandler::MoveCursor(
+void Gtk2KeyBindingsHandler::MoveCursor(
GtkTextView* text_view, GtkMovementStep step, gint count,
gboolean extend_selection) {
if (!count)
@@ -242,7 +297,7 @@ void GtkKeyBindingsHandler::MoveCursor(
return;
}
- GtkKeyBindingsHandler* owner = GetHandlerOwner(text_view);
+ Gtk2KeyBindingsHandler* owner = GetHandlerOwner(text_view);
if (extend_selection)
command.append("AndModifySelection");
if (count < 0)
@@ -251,43 +306,44 @@ void GtkKeyBindingsHandler::MoveCursor(
owner->EditCommandMatched(command, std::string());
}
-void GtkKeyBindingsHandler::MoveViewport(
+void Gtk2KeyBindingsHandler::MoveViewport(
GtkTextView* text_view, GtkScrollStep step, gint count) {
// Not supported by webkit.
}
-void GtkKeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::PasteClipboard(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched("Paste", std::string());
}
-void GtkKeyBindingsHandler::SelectAll(GtkTextView* text_view, gboolean select) {
+void Gtk2KeyBindingsHandler::SelectAll(GtkTextView* text_view,
+ gboolean select) {
if (select)
GetHandlerOwner(text_view)->EditCommandMatched("SelectAll", std::string());
else
GetHandlerOwner(text_view)->EditCommandMatched("Unselect", std::string());
}
-void GtkKeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::SetAnchor(GtkTextView* text_view) {
GetHandlerOwner(text_view)->EditCommandMatched("SetMark", std::string());
}
-void GtkKeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::ToggleCursorVisible(GtkTextView* text_view) {
// Not supported by webkit.
}
-void GtkKeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) {
+void Gtk2KeyBindingsHandler::ToggleOverwrite(GtkTextView* text_view) {
// Not supported by webkit.
}
-gboolean GtkKeyBindingsHandler::ShowHelp(GtkWidget* widget,
- GtkWidgetHelpType arg1) {
+gboolean Gtk2KeyBindingsHandler::ShowHelp(GtkWidget* widget,
+ GtkWidgetHelpType arg1) {
// Just for disabling the default handler.
return FALSE;
}
-void GtkKeyBindingsHandler::MoveFocus(GtkWidget* widget,
- GtkDirectionType arg1) {
+void Gtk2KeyBindingsHandler::MoveFocus(GtkWidget* widget,
+ GtkDirectionType arg1) {
// Just for disabling the default handler.
}
-} // namespace content
+} // namespace libgtk2ui

Powered by Google App Engine
This is Rietveld 408576698