OLD | NEW |
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 "ui/base/ime/input_method_ibus.h" | 5 #include "ui/base/ime/input_method_ibus.h" |
6 | 6 |
7 #include <X11/X.h> | 7 #include <X11/X.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
10 #undef FocusIn | 10 #undef FocusIn |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/logging.h" | 21 #include "base/logging.h" |
22 #include "base/string_util.h" | 22 #include "base/string_util.h" |
23 #include "base/third_party/icu/icu_utf.h" | 23 #include "base/third_party/icu/icu_utf.h" |
24 #include "base/utf_string_conversions.h" | 24 #include "base/utf_string_conversions.h" |
25 #include "chromeos/dbus/dbus_thread_manager.h" | 25 #include "chromeos/dbus/dbus_thread_manager.h" |
26 #include "chromeos/dbus/ibus/ibus_client.h" | 26 #include "chromeos/dbus/ibus/ibus_client.h" |
27 #include "chromeos/dbus/ibus/ibus_input_context_client.h" | 27 #include "chromeos/dbus/ibus/ibus_input_context_client.h" |
28 #include "chromeos/dbus/ibus/ibus_text.h" | 28 #include "chromeos/dbus/ibus/ibus_text.h" |
29 #include "ui/base/events/event_constants.h" | 29 #include "ui/base/events/event_constants.h" |
30 #include "ui/base/events/event_utils.h" | 30 #include "ui/base/events/event_utils.h" |
31 #include "ui/base/ime/ibus_client.h" | |
32 #include "ui/base/ime/text_input_client.h" | 31 #include "ui/base/ime/text_input_client.h" |
33 #include "ui/base/keycodes/keyboard_code_conversion.h" | 32 #include "ui/base/keycodes/keyboard_code_conversion.h" |
34 #include "ui/base/keycodes/keyboard_code_conversion_x.h" | 33 #include "ui/base/keycodes/keyboard_code_conversion_x.h" |
35 #include "ui/base/keycodes/keyboard_codes.h" | 34 #include "ui/base/keycodes/keyboard_codes.h" |
36 #include "ui/gfx/rect.h" | 35 #include "ui/gfx/rect.h" |
37 | 36 |
38 namespace { | 37 namespace { |
39 | 38 |
40 const int kIBusReleaseMask = 1 << 30; | 39 const int kIBusReleaseMask = 1 << 30; |
41 const char kClientName[] = "chrome"; | 40 const char kClientName[] = "chrome"; |
(...skipping 24 matching lines...) Expand all Loading... |
66 // Converts X flags to ibus key state flags. | 65 // Converts X flags to ibus key state flags. |
67 uint32 IBusStateFromXFlags(unsigned int flags) { | 66 uint32 IBusStateFromXFlags(unsigned int flags) { |
68 return (flags & (LockMask | ControlMask | ShiftMask | Mod1Mask | | 67 return (flags & (LockMask | ControlMask | ShiftMask | Mod1Mask | |
69 Button1Mask | Button2Mask | Button3Mask)); | 68 Button1Mask | Button2Mask | Button3Mask)); |
70 } | 69 } |
71 | 70 |
72 chromeos::IBusInputContextClient* GetInputContextClient() { | 71 chromeos::IBusInputContextClient* GetInputContextClient() { |
73 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); | 72 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); |
74 } | 73 } |
75 | 74 |
| 75 // Converts gfx::Rect to ibus::Rect. |
| 76 chromeos::ibus::Rect GfxRectToIBusRect(const gfx::Rect& rect) { |
| 77 return chromeos::ibus::Rect(rect.x(), rect.y(), rect.width(), rect.height()); |
| 78 } |
| 79 |
76 } // namespace | 80 } // namespace |
77 | 81 |
78 namespace ui { | 82 namespace ui { |
79 | 83 |
80 // InputMethodIBus implementation ----------------------------------------- | 84 // InputMethodIBus implementation ----------------------------------------- |
81 InputMethodIBus::InputMethodIBus( | 85 InputMethodIBus::InputMethodIBus( |
82 internal::InputMethodDelegate* delegate) | 86 internal::InputMethodDelegate* delegate) |
83 : ibus_client_(new internal::IBusClient), | 87 : input_context_state_(INPUT_CONTEXT_STOP), |
84 input_context_state_(INPUT_CONTEXT_STOP), | |
85 create_input_context_fail_count_(0), | 88 create_input_context_fail_count_(0), |
86 context_focused_(false), | 89 context_focused_(false), |
87 composing_text_(false), | 90 composing_text_(false), |
88 composition_changed_(false), | 91 composition_changed_(false), |
89 suppress_next_result_(false), | 92 suppress_next_result_(false), |
90 current_keyevent_id_(0), | 93 current_keyevent_id_(0), |
91 weak_ptr_factory_(this) { | 94 weak_ptr_factory_(this) { |
92 SetDelegate(delegate); | 95 SetDelegate(delegate); |
93 } | 96 } |
94 | 97 |
95 InputMethodIBus::~InputMethodIBus() { | 98 InputMethodIBus::~InputMethodIBus() { |
96 AbandonAllPendingKeyEvents(); | 99 AbandonAllPendingKeyEvents(); |
97 if (IsContextReady()) | 100 if (IsContextReady()) |
98 DestroyContext(); | 101 DestroyContext(); |
99 if (GetInputContextClient()) | 102 if (GetInputContextClient()) |
100 GetInputContextClient()->SetInputContextHandler(NULL); | 103 GetInputContextClient()->SetInputContextHandler(NULL); |
101 } | 104 } |
102 | 105 |
103 void InputMethodIBus::set_ibus_client( | |
104 scoped_ptr<internal::IBusClient> new_client) { | |
105 ibus_client_.swap(new_client); | |
106 } | |
107 | |
108 internal::IBusClient* InputMethodIBus::ibus_client() const { | |
109 return ibus_client_.get(); | |
110 } | |
111 | |
112 void InputMethodIBus::OnFocus() { | 106 void InputMethodIBus::OnFocus() { |
113 InputMethodBase::OnFocus(); | 107 InputMethodBase::OnFocus(); |
114 UpdateContextFocusState(); | 108 UpdateContextFocusState(); |
115 } | 109 } |
116 | 110 |
117 void InputMethodIBus::OnBlur() { | 111 void InputMethodIBus::OnBlur() { |
118 ConfirmCompositionText(); | 112 ConfirmCompositionText(); |
119 InputMethodBase::OnBlur(); | 113 InputMethodBase::OnBlur(); |
120 UpdateContextFocusState(); | 114 UpdateContextFocusState(); |
121 } | 115 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 IBusKeyEventFromNativeKeyEvent( | 154 IBusKeyEventFromNativeKeyEvent( |
161 native_event, &ibus_keyval, &ibus_keycode, &ibus_state); | 155 native_event, &ibus_keyval, &ibus_keycode, &ibus_state); |
162 | 156 |
163 // If |context_| is not usable, then we can only dispatch the key event as is. | 157 // If |context_| is not usable, then we can only dispatch the key event as is. |
164 // We also dispatch the key event directly if the current text input type is | 158 // We also dispatch the key event directly if the current text input type is |
165 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. | 159 // TEXT_INPUT_TYPE_PASSWORD, to bypass the input method. |
166 // Note: We need to send the key event to ibus even if the |context_| is not | 160 // Note: We need to send the key event to ibus even if the |context_| is not |
167 // enabled, so that ibus can have a chance to enable the |context_|. | 161 // enabled, so that ibus can have a chance to enable the |context_|. |
168 if (!context_focused_ || | 162 if (!context_focused_ || |
169 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || | 163 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || |
170 ibus_client_->GetInputMethodType() == | 164 !GetInputContextClient() || |
171 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) { | 165 GetInputContextClient()->IsXKBLayout()) { |
172 if (native_event->type == KeyPress) | 166 if (native_event->type == KeyPress) |
173 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); | 167 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); |
174 else | 168 else |
175 DispatchKeyEventPostIME(native_event); | 169 DispatchKeyEventPostIME(native_event); |
176 return; | 170 return; |
177 } | 171 } |
178 | 172 |
179 pending_key_events_.insert(current_keyevent_id_); | 173 pending_key_events_.insert(current_keyevent_id_); |
180 | 174 |
181 // Since |native_event| might be treated as XEvent whose size is bigger than | 175 // Since |native_event| might be treated as XEvent whose size is bigger than |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 // The current text input type should not be NONE if |context_| is focused. | 214 // The current text input type should not be NONE if |context_| is focused. |
221 DCHECK(!IsTextInputTypeNone()); | 215 DCHECK(!IsTextInputTypeNone()); |
222 const gfx::Rect rect = GetTextInputClient()->GetCaretBounds(); | 216 const gfx::Rect rect = GetTextInputClient()->GetCaretBounds(); |
223 | 217 |
224 gfx::Rect composition_head; | 218 gfx::Rect composition_head; |
225 if (!GetTextInputClient()->GetCompositionCharacterBounds(0, | 219 if (!GetTextInputClient()->GetCompositionCharacterBounds(0, |
226 &composition_head)) { | 220 &composition_head)) { |
227 composition_head = rect; | 221 composition_head = rect; |
228 } | 222 } |
229 | 223 |
230 // This function runs asynchronously. | 224 GetInputContextClient()->SetCursorLocation( |
231 ibus_client_->SetCursorLocation(rect, composition_head); | 225 GfxRectToIBusRect(rect), |
| 226 GfxRectToIBusRect(composition_head)); |
232 | 227 |
233 ui::Range text_range; | 228 ui::Range text_range; |
234 ui::Range selection_range; | 229 ui::Range selection_range; |
235 string16 surrounding_text; | 230 string16 surrounding_text; |
236 if (!GetTextInputClient()->GetTextRange(&text_range) || | 231 if (!GetTextInputClient()->GetTextRange(&text_range) || |
237 !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) || | 232 !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) || |
238 !GetTextInputClient()->GetSelectionRange(&selection_range)) { | 233 !GetTextInputClient()->GetSelectionRange(&selection_range)) { |
239 previous_surrounding_text_.clear(); | 234 previous_surrounding_text_.clear(); |
240 previous_selection_range_ = ui::Range::InvalidRange(); | 235 previous_selection_range_ = ui::Range::InvalidRange(); |
241 return; | 236 return; |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 } | 909 } |
915 | 910 |
916 // Use a black thin underline by default. | 911 // Use a black thin underline by default. |
917 if (out_composition->underlines.empty()) { | 912 if (out_composition->underlines.empty()) { |
918 out_composition->underlines.push_back(CompositionUnderline( | 913 out_composition->underlines.push_back(CompositionUnderline( |
919 0, length, SK_ColorBLACK, false /* thick */)); | 914 0, length, SK_ColorBLACK, false /* thick */)); |
920 } | 915 } |
921 } | 916 } |
922 | 917 |
923 } // namespace ui | 918 } // namespace ui |
OLD | NEW |