| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_GTK_IM_CONTEXT_WRAPPER_H_ | |
| 6 #define CONTENT_BROWSER_RENDERER_HOST_GTK_IM_CONTEXT_WRAPPER_H_ | |
| 7 | |
| 8 #include <gdk/gdk.h> | |
| 9 #include <pango/pango-attributes.h> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/gtest_prod_util.h" | |
| 14 #include "base/strings/string16.h" | |
| 15 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
| 16 #include "ui/base/ime/composition_text.h" | |
| 17 #include "ui/base/ime/text_input_type.h" | |
| 18 | |
| 19 typedef struct _GtkIMContext GtkIMContext; | |
| 20 typedef struct _GtkWidget GtkWidget; | |
| 21 | |
| 22 namespace gfx { | |
| 23 class Rect; | |
| 24 } | |
| 25 | |
| 26 namespace content { | |
| 27 class RenderWidgetHostViewGtk; | |
| 28 struct NativeWebKeyboardEvent; | |
| 29 | |
| 30 // This class is a convenience wrapper for GtkIMContext. | |
| 31 // It creates and manages two GtkIMContext instances, one is GtkIMMulticontext, | |
| 32 // for plain text input box, another is GtkIMContextSimple, for password input | |
| 33 // box. | |
| 34 // | |
| 35 // This class is in charge of dispatching key events to these two GtkIMContext | |
| 36 // instances and handling signals emitted by them. Key events then will be | |
| 37 // forwarded to renderer along with input method results via corresponding host | |
| 38 // view. | |
| 39 // | |
| 40 // This class is used solely by RenderWidgetHostViewGtk. | |
| 41 class GtkIMContextWrapper { | |
| 42 public: | |
| 43 explicit GtkIMContextWrapper(RenderWidgetHostViewGtk* host_view); | |
| 44 ~GtkIMContextWrapper(); | |
| 45 | |
| 46 // Processes a gdk key event received by |host_view|. | |
| 47 void ProcessKeyEvent(GdkEventKey* event); | |
| 48 | |
| 49 void UpdateInputMethodState(ui::TextInputType type, | |
| 50 bool can_compose_inline); | |
| 51 void UpdateCaretBounds(const gfx::Rect& caret_bounds); | |
| 52 void OnFocusIn(); | |
| 53 void OnFocusOut(); | |
| 54 bool is_focused() const { return is_focused_; } | |
| 55 | |
| 56 GtkWidget* BuildInputMethodsGtkMenu(); | |
| 57 | |
| 58 void CancelComposition(); | |
| 59 | |
| 60 void ConfirmComposition(); | |
| 61 | |
| 62 private: | |
| 63 // Check if a text needs commit by forwarding a char event instead of | |
| 64 // by confirming as a composition text. | |
| 65 bool NeedCommitByForwardingCharEvent() const; | |
| 66 | |
| 67 // Check if the input method returned any result, eg. preedit and commit text. | |
| 68 bool HasInputMethodResult() const; | |
| 69 | |
| 70 void ProcessFilteredKeyPressEvent(NativeWebKeyboardEvent* wke); | |
| 71 void ProcessUnfilteredKeyPressEvent(NativeWebKeyboardEvent* wke); | |
| 72 | |
| 73 // Processes result returned from input method after filtering a key event. | |
| 74 // |filtered| indicates if the key event was filtered by the input method. | |
| 75 void ProcessInputMethodResult(const GdkEventKey* event, bool filtered); | |
| 76 | |
| 77 // Real code of "commit" signal handler. | |
| 78 void HandleCommit(const base::string16& text); | |
| 79 | |
| 80 // Real code of "preedit-start" signal handler. | |
| 81 void HandlePreeditStart(); | |
| 82 | |
| 83 // Real code of "preedit-changed" signal handler. | |
| 84 void HandlePreeditChanged(const gchar* text, | |
| 85 PangoAttrList* attrs, | |
| 86 int cursor_position); | |
| 87 | |
| 88 // Real code of "preedit-end" signal handler. | |
| 89 void HandlePreeditEnd(); | |
| 90 | |
| 91 // Real code of "retrieve-surrounding" signal handler. | |
| 92 gboolean HandleRetrieveSurrounding(GtkIMContext* context); | |
| 93 | |
| 94 // Real code of "realize" signal handler, used for setting im context's client | |
| 95 // window. | |
| 96 void HandleHostViewRealize(GtkWidget* widget); | |
| 97 | |
| 98 // Real code of "unrealize" signal handler, used for unsetting im context's | |
| 99 // client window. | |
| 100 void HandleHostViewUnrealize(); | |
| 101 | |
| 102 // Sends a fake composition key event with specified event type. A composition | |
| 103 // key event is a key event with special key code 229. | |
| 104 void SendFakeCompositionKeyEvent(blink::WebInputEvent::Type type); | |
| 105 | |
| 106 // Signal handlers of GtkIMContext object. | |
| 107 static void HandleCommitThunk(GtkIMContext* context, gchar* text, | |
| 108 GtkIMContextWrapper* self); | |
| 109 static void HandlePreeditStartThunk(GtkIMContext* context, | |
| 110 GtkIMContextWrapper* self); | |
| 111 static void HandlePreeditChangedThunk(GtkIMContext* context, | |
| 112 GtkIMContextWrapper* self); | |
| 113 static void HandlePreeditEndThunk(GtkIMContext* context, | |
| 114 GtkIMContextWrapper* self); | |
| 115 static gboolean HandleRetrieveSurroundingThunk(GtkIMContext* context, | |
| 116 GtkIMContextWrapper* self); | |
| 117 | |
| 118 // Signal handlers connecting to |host_view_|'s native view widget. | |
| 119 static void HandleHostViewRealizeThunk(GtkWidget* widget, | |
| 120 GtkIMContextWrapper* self); | |
| 121 static void HandleHostViewUnrealizeThunk(GtkWidget* widget, | |
| 122 GtkIMContextWrapper* self); | |
| 123 | |
| 124 // The parent object. | |
| 125 RenderWidgetHostViewGtk* host_view_; | |
| 126 | |
| 127 // The GtkIMContext object. | |
| 128 // In terms of the DOM event specification Appendix A | |
| 129 // <http://www.w3.org/TR/DOM-Level-3-Events/keyset.html>, | |
| 130 // GTK uses a GtkIMContext object for the following two purposes: | |
| 131 // 1. Composing Latin characters (A.1.2), and; | |
| 132 // 2. Composing CJK characters with an IME (A.1.3). | |
| 133 // Many JavaScript pages assume composed Latin characters are dispatched to | |
| 134 // their onkeypress() handlers but not dispatched CJK characters composed | |
| 135 // with an IME. To emulate this behavior, we should monitor the status of | |
| 136 // this GtkIMContext object and prevent sending Char events when a | |
| 137 // GtkIMContext object sends a "commit" signal with the CJK characters | |
| 138 // composed by an IME. | |
| 139 GtkIMContext* context_; | |
| 140 | |
| 141 // A GtkIMContextSimple object, for supporting dead/compose keys when input | |
| 142 // method is disabled, eg. in password input box. | |
| 143 GtkIMContext* context_simple_; | |
| 144 | |
| 145 // Whether or not this widget is focused. | |
| 146 bool is_focused_; | |
| 147 | |
| 148 // Whether or not the above GtkIMContext is composing a text with an IME. | |
| 149 // This flag is used in "commit" signal handler of the GtkIMContext object, | |
| 150 // which determines how to submit the result text to WebKit according to this | |
| 151 // flag. | |
| 152 // If this flag is true or there are more than one characters in the result, | |
| 153 // then the result text will be committed to WebKit as a confirmed | |
| 154 // composition. Otherwise, it'll be forwarded as a key event. | |
| 155 // | |
| 156 // The GtkIMContext object sends a "preedit_start" before it starts composing | |
| 157 // a text and a "preedit_end" signal after it finishes composing it. | |
| 158 // "preedit_start" signal is monitored to turn it on. | |
| 159 // We don't monitor "preedit_end" signal to turn it off, because an input | |
| 160 // method may fire "preedit_end" signal before "commit" signal. | |
| 161 // A buggy input method may not fire "preedit_start" and/or "preedit_end" | |
| 162 // at all, so this flag will also be set to true when "preedit_changed" signal | |
| 163 // is fired with non-empty preedit text. | |
| 164 bool is_composing_text_; | |
| 165 | |
| 166 // Whether or not the IME is enabled. | |
| 167 bool is_enabled_; | |
| 168 | |
| 169 // Whether or not it's currently running inside key event handler. | |
| 170 // If it's true, then preedit-changed and commit handler will backup the | |
| 171 // preedit or commit text instead of sending them down to webkit. | |
| 172 // key event handler will send them later. | |
| 173 bool is_in_key_event_handler_; | |
| 174 | |
| 175 // The most recent composition text information retrieved from context_; | |
| 176 ui::CompositionText composition_; | |
| 177 | |
| 178 // Whether or not the composition has been changed since last key event. | |
| 179 bool is_composition_changed_; | |
| 180 | |
| 181 // Stores a copy of the most recent commit text received by commit signal | |
| 182 // handler. | |
| 183 base::string16 commit_text_; | |
| 184 | |
| 185 // If it's true then the next "commit" signal will be suppressed. | |
| 186 // It's only used to workaround http://crbug.com/50485. | |
| 187 // TODO(suzhe): Remove it after input methods get fixed. | |
| 188 bool suppress_next_commit_; | |
| 189 | |
| 190 // Information of the last key event, for working around | |
| 191 // http://crosbug.com/6582 | |
| 192 int last_key_code_; | |
| 193 bool last_key_was_up_; | |
| 194 bool last_key_filtered_no_result_; | |
| 195 | |
| 196 DISALLOW_COPY_AND_ASSIGN(GtkIMContextWrapper); | |
| 197 }; | |
| 198 | |
| 199 } // namespace content | |
| 200 | |
| 201 #endif // CONTENT_BROWSER_RENDERER_HOST_GTK_IM_CONTEXT_WRAPPER_H_ | |
| OLD | NEW |