1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file. 4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#ifndef CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_ 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#define CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_ 7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <gtk/gtk.h> 9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <string> 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <vector> 12e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/event_types.h" 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/libgtk2ui/owned_widget_gtk2.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/linux/text_edit_command_auralinux.h" 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace content { 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochstruct NativeWebKeyboardEvent; 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace ui { 22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass Event; 23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace libgtk2ui { 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// This class is a convenience class for handling editor key bindings defined 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// in gtk keyboard theme. 29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// In gtk, only GtkEntry and GtkTextView support customizing editor key bindings 30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// through keyboard theme. And in gtk keyboard theme definition file, each key 31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// binding must be bound to a specific class or object. So existing keyboard 32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// themes only define editor key bindings exactly for GtkEntry and GtkTextView. 33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Then, the only way for us to intercept editor key bindings defined in 34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// keyboard theme, is to create a GtkEntry or GtkTextView object and call 35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// gtk_bindings_activate_event() against it for the key events. If a key event 36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// matches a predefined key binding, corresponding signal will be emitted. 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// GtkTextView is used here because it supports more key bindings than GtkEntry, 38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// but in order to minimize the side effect of using a GtkTextView object, a new 39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// class derived from GtkTextView is used, which overrides all signals related 40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// to key bindings, to make sure GtkTextView won't receive them. 41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// See third_party/WebKit/Source/WebCore/editing/EditorCommand.cpp for detailed 43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// definition of webkit edit commands. 44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// See webkit/glue/editor_client_impl.cc for key bindings predefined in our 45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// webkit glue. 46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass Gtk2KeyBindingsHandler { 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Gtk2KeyBindingsHandler(); 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual ~Gtk2KeyBindingsHandler(); 50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Matches a key event against predefined gtk key bindings, false will be 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // returned if the key event doesn't correspond to a predefined key binding. 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Edit commands matched with |event| will be stored in |edit_commands|, if 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // non-NULL. 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool MatchEvent(const ui::Event& event, 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<ui::TextEditCommandAuraLinux>* commands); 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private: 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Object structure of Handler class, which is derived from GtkTextView. 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch struct Handler { 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GtkTextView parent_object; 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Gtk2KeyBindingsHandler *owner; 63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch }; 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Class structure of Handler class. 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch struct HandlerClass { 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GtkTextViewClass parent_class; 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch }; 69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Creates a new instance of Handler class. 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GtkWidget* CreateNewHandler(); 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Adds an edit command to the key event. 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch void EditCommandMatched(ui::TextEditCommandAuraLinux::CommandId id, 75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const std::string& value, 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool extend_selection); 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Builds a fake GdkEventKey from an XEvent. 79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void BuildGdkEventKeyFromXEvent(const base::NativeEvent& xevent, 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GdkEventKey* gdk_event); 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Initializes Handler structure. 83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void HandlerInit(Handler *self); 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Initializes HandlerClass structure. 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void HandlerClassInit(HandlerClass *klass); 87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Registeres Handler class to GObject type system and return its type id. 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static GType HandlerGetType(); 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Gets the Gtk2KeyBindingsHandler object which owns the Handler object. 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static Gtk2KeyBindingsHandler* GetHandlerOwner(GtkTextView* text_view); 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "backspace" signal. 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void BackSpace(GtkTextView* text_view); 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "copy-clipboard" signal. 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void CopyClipboard(GtkTextView* text_view); 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "cut-clipboard" signal. 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void CutClipboard(GtkTextView* text_view); 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "delete-from-cursor" signal. 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void DeleteFromCursor(GtkTextView* text_view, GtkDeleteType type, 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gint count); 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "insert-at-cursor" signal. 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void InsertAtCursor(GtkTextView* text_view, const gchar* str); 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "move-cursor" signal. 111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void MoveCursor(GtkTextView* text_view, GtkMovementStep step, 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gint count, gboolean extend_selection); 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "move-viewport" signal. 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void MoveViewport(GtkTextView* text_view, GtkScrollStep step, 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gint count); 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "paste-clipboard" signal. 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void PasteClipboard(GtkTextView* text_view); 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "select-all" signal. 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void SelectAll(GtkTextView* text_view, gboolean select); 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "set-anchor" signal. 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void SetAnchor(GtkTextView* text_view); 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "toggle-cursor-visible" signal. 128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void ToggleCursorVisible(GtkTextView* text_view); 129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "toggle-overwrite" signal. 131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void ToggleOverwrite(GtkTextView* text_view); 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "show-help" signal. 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static gboolean ShowHelp(GtkWidget* widget, GtkWidgetHelpType arg1); 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Handler of "move-focus" signal. 137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static void MoveFocus(GtkWidget* widget, GtkDirectionType arg1); 138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GtkWidget* fake_window_; 140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch libgtk2ui::OwnedWidgetGtk handler_; 142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Buffer to store the match results. 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<ui::TextEditCommandAuraLinux> edit_commands_; 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Whether the current X server has the XKeyboard extension. 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool has_xkb_; 148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}; 149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace libgtk2ui 151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif // CHROME_BROWSER_UI_LIBGTK2UI_GTK2_KEY_BINDINGS_HANDLER_H_ 153