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

Side by Side Diff: ui/base/ime/input_method_ibus.cc

Issue 10656017: Clean UP: Remove IBusClientImpl from ui/base/ime/* (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix WinAura Created 8 years, 5 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
« no previous file with comments | « ui/base/ime/input_method_ibus.h ('k') | ui/base/ime/input_method_ibus_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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
11 #undef FocusOut 11 #undef FocusOut
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <cstring> 14 #include <cstring>
15 #include <set> 15 #include <set>
16 #include <vector> 16 #include <vector>
17 17
18 #include "base/basictypes.h" 18 #include "base/basictypes.h"
19 #include "base/bind.h" 19 #include "base/bind.h"
20 #include "base/i18n/char_iterator.h" 20 #include "base/i18n/char_iterator.h"
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_input_context_client.h" 27 #include "chromeos/dbus/ibus/ibus_input_context_client.h"
27 #include "chromeos/dbus/ibus/ibus_text.h" 28 #include "chromeos/dbus/ibus/ibus_text.h"
28 #include "ui/base/events.h" 29 #include "ui/base/events.h"
29 #include "ui/base/ime/ibus_client_impl.h" 30 #include "ui/base/ime/ibus_client.h"
30 #include "ui/base/ime/text_input_client.h" 31 #include "ui/base/ime/text_input_client.h"
31 #include "ui/base/keycodes/keyboard_code_conversion.h" 32 #include "ui/base/keycodes/keyboard_code_conversion.h"
32 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 33 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
33 #include "ui/base/keycodes/keyboard_codes.h" 34 #include "ui/base/keycodes/keyboard_codes.h"
34 #include "ui/gfx/rect.h" 35 #include "ui/gfx/rect.h"
35 36
36 namespace { 37 namespace {
37 38
38 const int kIBusReleaseMask = 1 << 30; 39 const int kIBusReleaseMask = 1 << 30;
40 const char kClientName[] = "chrome";
41
42 // Following capability mask is introduced from
43 // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabili te
44 const uint32 kIBusCapabilityPreeditText = 1U;
45 const uint32 kIBusCapabilityFocus = 8U;
39 46
40 XKeyEvent* GetKeyEvent(XEvent* event) { 47 XKeyEvent* GetKeyEvent(XEvent* event) {
41 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); 48 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease));
42 return &event->xkey; 49 return &event->xkey;
43 } 50 }
44 51
45 // Converts X (and ibus) flags to event flags. 52 // Converts X (and ibus) flags to event flags.
46 int EventFlagsFromXFlags(unsigned int flags) { 53 int EventFlagsFromXFlags(unsigned int flags) {
47 return (flags & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) | 54 return (flags & LockMask ? ui::EF_CAPS_LOCK_DOWN : 0) |
48 (flags & ControlMask ? ui::EF_CONTROL_DOWN : 0) | 55 (flags & ControlMask ? ui::EF_CONTROL_DOWN : 0) |
(...skipping 21 matching lines...) Expand all
70 // translate Shift and CapsLock states. 77 // translate Shift and CapsLock states.
71 KeySym keysym = NoSymbol; 78 KeySym keysym = NoSymbol;
72 ::XLookupString(x_key, NULL, 0, &keysym, NULL); 79 ::XLookupString(x_key, NULL, 0, &keysym, NULL);
73 *ibus_keyval = keysym; 80 *ibus_keyval = keysym;
74 *ibus_keycode = x_key->keycode; 81 *ibus_keycode = x_key->keycode;
75 *ibus_state = IBusStateFromXFlags(x_key->state); 82 *ibus_state = IBusStateFromXFlags(x_key->state);
76 if (native_event->type == KeyRelease) 83 if (native_event->type == KeyRelease)
77 *ibus_state |= kIBusReleaseMask; 84 *ibus_state |= kIBusReleaseMask;
78 } 85 }
79 86
87 chromeos::IBusInputContextClient* GetInputContextClient() {
88 return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
89 }
90
80 } // namespace 91 } // namespace
81 92
82 namespace ui { 93 namespace ui {
83 94
84 // InputMethodIBus::PendingKeyEventImpl implementation ------------------------ 95 // A class to hold all data related to a key event being processed by the input
85 class InputMethodIBus::PendingKeyEventImpl 96 // method but still has no result back yet.
86 : public internal::IBusClient::PendingKeyEvent { 97 class InputMethodIBus::PendingKeyEvent {
87 public: 98 public:
88 PendingKeyEventImpl(InputMethodIBus* input_method, 99 PendingKeyEvent(InputMethodIBus* input_method,
89 const base::NativeEvent& native_event, 100 const base::NativeEvent& native_event,
90 uint32 ibus_keyval); 101 uint32 ibus_keyval);
91 virtual ~PendingKeyEventImpl(); 102 virtual ~PendingKeyEvent();
92 103
93 // internal::IBusClient::PendingKeyEvent overrides: 104 // Process this pending key event after we receive its result from the input
94 virtual void ProcessPostIME(bool handled) OVERRIDE; 105 // method. It just call through InputMethodIBus::ProcessKeyEventPostIME().
106 void ProcessPostIME(bool handled);
95 107
96 // Abandon this pending key event. Its result will just be discarded. 108 // Abandon this pending key event. Its result will just be discarded.
97 void Abandon() { input_method_ = NULL; } 109 void Abandon() { input_method_ = NULL; }
98 110
99 InputMethodIBus* input_method() const { return input_method_; } 111 InputMethodIBus* input_method() const { return input_method_; }
100 112
101 private: 113 private:
102 InputMethodIBus* input_method_; 114 InputMethodIBus* input_method_;
103 115
104 // TODO(yusukes): To support a fabricated key event (which is typically from 116 // TODO(yusukes): To support a fabricated key event (which is typically from
105 // a virtual keyboard), we might have to copy event type, event flags, key 117 // a virtual keyboard), we might have to copy event type, event flags, key
106 // code, 'character_', and 'unmodified_character_'. See views::InputMethodIBus 118 // code, 'character_', and 'unmodified_character_'. See views::InputMethodIBus
107 // for details. 119 // for details.
108 120
109 // corresponding XEvent data of a key event. It's a plain struct so we can do 121 // corresponding XEvent data of a key event. It's a plain struct so we can do
110 // bitwise copy. 122 // bitwise copy.
111 XKeyEvent x_event_; 123 XKeyEvent x_event_;
112 124
113 const uint32 ibus_keyval_; 125 const uint32 ibus_keyval_;
114 126
115 DISALLOW_COPY_AND_ASSIGN(PendingKeyEventImpl); 127 DISALLOW_COPY_AND_ASSIGN(PendingKeyEvent);
116 }; 128 };
117 129
118 InputMethodIBus::PendingKeyEventImpl::PendingKeyEventImpl( 130 InputMethodIBus::PendingKeyEvent::PendingKeyEvent(
119 InputMethodIBus* input_method, 131 InputMethodIBus* input_method,
120 const base::NativeEvent& native_event, 132 const base::NativeEvent& native_event,
121 uint32 ibus_keyval) 133 uint32 ibus_keyval)
122 : input_method_(input_method), 134 : input_method_(input_method),
123 ibus_keyval_(ibus_keyval) { 135 ibus_keyval_(ibus_keyval) {
124 DCHECK(input_method_); 136 DCHECK(input_method_);
125 137
126 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). 138 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard).
127 DCHECK(native_event); 139 DCHECK(native_event);
128 x_event_ = *GetKeyEvent(native_event); 140 x_event_ = *GetKeyEvent(native_event);
129 } 141 }
130 142
131 InputMethodIBus::PendingKeyEventImpl::~PendingKeyEventImpl() { 143 InputMethodIBus::PendingKeyEvent::~PendingKeyEvent() {
132 if (input_method_) 144 if (input_method_)
133 input_method_->FinishPendingKeyEvent(this); 145 input_method_->FinishPendingKeyEvent(this);
134 } 146 }
135 147
136 void InputMethodIBus::PendingKeyEventImpl::ProcessPostIME(bool handled) { 148 void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) {
137 if (!input_method_) 149 if (!input_method_)
138 return; 150 return;
139 151
140 if (x_event_.type == KeyPress || x_event_.type == KeyRelease) { 152 if (x_event_.type == KeyPress || x_event_.type == KeyRelease) {
141 input_method_->ProcessKeyEventPostIME(reinterpret_cast<XEvent*>(&x_event_), 153 input_method_->ProcessKeyEventPostIME(reinterpret_cast<XEvent*>(&x_event_),
142 ibus_keyval_, 154 ibus_keyval_,
143 handled); 155 handled);
144 return; 156 return;
145 } 157 }
146 158
147 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). 159 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard).
148 // See views::InputMethodIBus for details. Never forget to set 'character_' 160 // See views::InputMethodIBus for details. Never forget to set 'character_'
149 // and 'unmodified_character_' to support i18n VKs like a French VK! 161 // and 'unmodified_character_' to support i18n VKs like a French VK!
150 } 162 }
151 163
152 // InputMethodIBus::PendingCreateICRequestImpl implementation ----------------- 164 // A class to hold information of a pending request for creating an ibus input
153 class InputMethodIBus::PendingCreateICRequestImpl 165 // context.
154 : public internal::IBusClient::PendingCreateICRequest { 166 class InputMethodIBus::PendingCreateICRequest {
155 public: 167 public:
156 PendingCreateICRequestImpl(InputMethodIBus* input_method, 168 PendingCreateICRequest(InputMethodIBus* input_method,
157 internal::IBusClient* ibus_client, 169 PendingCreateICRequest** request_ptr);
158 PendingCreateICRequestImpl** request_ptr); 170 virtual ~PendingCreateICRequest();
159 virtual ~PendingCreateICRequestImpl();
160 171
161 // internal::IBusClient::PendingCreateICRequest overrides: 172 // Set up signal handlers, or destroy object proxy if the input context is
162 virtual void InitOrAbandonInputContext() OVERRIDE; 173 // already abandoned.
163 virtual void OnCreateInputContextFailed() OVERRIDE; 174 void InitOrAbandonInputContext();
175
176 // Called if the create input context method call is failed.
177 void OnCreateInputContextFailed();
164 178
165 // Abandon this pending key event. Its result will just be discarded. 179 // Abandon this pending key event. Its result will just be discarded.
166 void Abandon() { 180 void Abandon() {
167 input_method_ = NULL; 181 input_method_ = NULL;
168 request_ptr_ = NULL; 182 request_ptr_ = NULL;
169 // Do not reset |ibus_client_| here. 183 // Do not reset |ibus_client_| here.
170 } 184 }
171 185
172 private: 186 private:
173 InputMethodIBus* input_method_; 187 InputMethodIBus* input_method_;
174 internal::IBusClient* ibus_client_; 188 PendingCreateICRequest** request_ptr_;
175 PendingCreateICRequestImpl** request_ptr_;
176 189
177 DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequestImpl); 190 DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequest);
178 }; 191 };
179 192
180 InputMethodIBus::PendingCreateICRequestImpl::PendingCreateICRequestImpl( 193 InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest(
181 InputMethodIBus* input_method, 194 InputMethodIBus* input_method,
182 internal::IBusClient* ibus_client, 195 PendingCreateICRequest** request_ptr)
183 PendingCreateICRequestImpl** request_ptr)
184 : input_method_(input_method), 196 : input_method_(input_method),
185 ibus_client_(ibus_client),
186 request_ptr_(request_ptr) { 197 request_ptr_(request_ptr) {
187 } 198 }
188 199
189 InputMethodIBus::PendingCreateICRequestImpl::~PendingCreateICRequestImpl() { 200 InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() {
190 if (request_ptr_) { 201 if (request_ptr_) {
191 DCHECK_EQ(*request_ptr_, this); 202 DCHECK_EQ(*request_ptr_, this);
192 *request_ptr_ = NULL; 203 *request_ptr_ = NULL;
193 } 204 }
194 } 205 }
195 206
196 void InputMethodIBus::PendingCreateICRequestImpl::OnCreateInputContextFailed() { 207 void InputMethodIBus::PendingCreateICRequest::OnCreateInputContextFailed() {
197 // TODO(nona): If the connection between Chrome and ibus-daemon terminates 208 // TODO(nona): If the connection between Chrome and ibus-daemon terminates
198 // for some reason, the create ic request will fail. We might want to call 209 // for some reason, the create ic request will fail. We might want to call
199 // ibus_client_->CreateContext() again after some delay. 210 // ibus_client_->CreateContext() again after some delay.
200 } 211 }
201 212
202 void InputMethodIBus::PendingCreateICRequestImpl::InitOrAbandonInputContext() { 213 void InputMethodIBus::PendingCreateICRequest::InitOrAbandonInputContext() {
203 if (input_method_) { 214 if (input_method_) {
204 DCHECK(ibus_client_->IsContextReady()); 215 DCHECK(input_method_->IsContextReady());
205 input_method_->SetUpSignalHandlers(); 216 input_method_->SetUpSignalHandlers();
206 } else { 217 } else {
207 ibus_client_->DestroyProxy(); 218 GetInputContextClient()->ResetObjectProxy();
208 DCHECK(!ibus_client_->IsContextReady());
209 } 219 }
210 } 220 }
211 221
212 // InputMethodIBus implementation ----------------------------------------- 222 // InputMethodIBus implementation -----------------------------------------
213 InputMethodIBus::InputMethodIBus( 223 InputMethodIBus::InputMethodIBus(
214 internal::InputMethodDelegate* delegate) 224 internal::InputMethodDelegate* delegate)
215 : 225 : ibus_client_(new internal::IBusClient),
216 ibus_client_(new internal::IBusClientImpl),
217 pending_create_ic_request_(NULL), 226 pending_create_ic_request_(NULL),
218 context_focused_(false), 227 context_focused_(false),
219 composing_text_(false), 228 composing_text_(false),
220 composition_changed_(false), 229 composition_changed_(false),
221 suppress_next_result_(false), 230 suppress_next_result_(false),
222 weak_ptr_factory_(this) { 231 weak_ptr_factory_(this) {
223 SetDelegate(delegate); 232 SetDelegate(delegate);
224 } 233 }
225 234
226 InputMethodIBus::~InputMethodIBus() { 235 InputMethodIBus::~InputMethodIBus() {
227 AbandonAllPendingKeyEvents(); 236 AbandonAllPendingKeyEvents();
228 if (ibus_client_->IsContextReady()) 237 if (IsContextReady())
229 DestroyContext(); 238 DestroyContext();
230 } 239 }
231 240
232 void InputMethodIBus::set_ibus_client( 241 void InputMethodIBus::set_ibus_client(
233 scoped_ptr<internal::IBusClient> new_client) { 242 scoped_ptr<internal::IBusClient> new_client) {
234 ibus_client_.swap(new_client); 243 ibus_client_.swap(new_client);
235 } 244 }
236 245
237 internal::IBusClient* InputMethodIBus::ibus_client() const { 246 internal::IBusClient* InputMethodIBus::ibus_client() const {
238 return ibus_client_.get(); 247 return ibus_client_.get();
239 } 248 }
240 249
241 void InputMethodIBus::OnFocus() { 250 void InputMethodIBus::OnFocus() {
242 InputMethodBase::OnFocus(); 251 InputMethodBase::OnFocus();
243 UpdateContextFocusState(); 252 UpdateContextFocusState();
244 } 253 }
245 254
246 void InputMethodIBus::OnBlur() { 255 void InputMethodIBus::OnBlur() {
247 ConfirmCompositionText(); 256 ConfirmCompositionText();
248 InputMethodBase::OnBlur(); 257 InputMethodBase::OnBlur();
249 UpdateContextFocusState(); 258 UpdateContextFocusState();
250 } 259 }
251 260
252 void InputMethodIBus::Init(bool focused) { 261 void InputMethodIBus::Init(bool focused) {
253 // Initializes the connection to ibus daemon. It may happen asynchronously, 262 // Initializes the connection to ibus daemon. It may happen asynchronously,
254 // and as soon as the connection is established, the |context_| will be 263 // and as soon as the connection is established, the |context_| will be
255 // created automatically. 264 // created automatically.
256 265
257 // Create the input context if the connection is already established. 266 // Create the input context if the connection is already established.
258 if (ibus_client_->IsConnected()) 267 if (IsConnected())
259 CreateContext(); 268 CreateContext();
260 269
261 InputMethodBase::Init(focused); 270 InputMethodBase::Init(focused);
262 } 271 }
263 272
264 // static 273 // static
265 void InputMethodIBus::ProcessKeyEventDone( 274 void InputMethodIBus::ProcessKeyEventDone(
266 PendingKeyEventImpl* pending_key_event, bool is_handled) { 275 PendingKeyEvent* pending_key_event, bool is_handled) {
267 DCHECK(pending_key_event); 276 DCHECK(pending_key_event);
268 pending_key_event->ProcessPostIME(is_handled); 277 pending_key_event->ProcessPostIME(is_handled);
269 delete pending_key_event; 278 delete pending_key_event;
270 } 279 }
271 280
272 void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { 281 void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) {
273 DCHECK(native_event && (native_event->type == KeyPress || 282 DCHECK(native_event && (native_event->type == KeyPress ||
274 native_event->type == KeyRelease)); 283 native_event->type == KeyRelease));
275 DCHECK(system_toplevel_window_focused()); 284 DCHECK(system_toplevel_window_focused());
276 285
(...skipping 12 matching lines...) Expand all
289 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || 298 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD ||
290 ibus_client_->GetInputMethodType() == 299 ibus_client_->GetInputMethodType() ==
291 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) { 300 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) {
292 if (native_event->type == KeyPress) 301 if (native_event->type == KeyPress)
293 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); 302 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval);
294 else 303 else
295 DispatchKeyEventPostIME(native_event); 304 DispatchKeyEventPostIME(native_event);
296 return; 305 return;
297 } 306 }
298 307
299 PendingKeyEventImpl* pending_key = 308 PendingKeyEvent* pending_key =
300 new PendingKeyEventImpl(this, native_event, ibus_keyval); 309 new PendingKeyEvent(this, native_event, ibus_keyval);
301 pending_key_events_.insert(pending_key); 310 pending_key_events_.insert(pending_key);
302 311
303 ibus_client_->SendKeyEvent(ibus_keyval, 312 GetInputContextClient()->ProcessKeyEvent(
304 ibus_keycode, 313 ibus_keyval,
305 ibus_state, 314 ibus_keycode,
306 base::Bind(&InputMethodIBus::ProcessKeyEventDone, 315 ibus_state, base::Bind(&InputMethodIBus::ProcessKeyEventDone,
307 base::Unretained(pending_key))); 316 base::Unretained(pending_key)));
308 317
309 // We don't want to suppress the result generated by this key event, but it 318 // We don't want to suppress the result generated by this key event, but it
310 // may cause problem. See comment in ResetContext() method. 319 // may cause problem. See comment in ResetContext() method.
311 suppress_next_result_ = false; 320 suppress_next_result_ = false;
312 } 321 }
313 322
314 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { 323 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) {
315 if (ibus_client_->IsContextReady() && IsTextInputClientFocused(client)) { 324 if (IsContextReady() && IsTextInputClientFocused(client)) {
316 ResetContext(); 325 ResetContext();
317 UpdateContextFocusState(); 326 UpdateContextFocusState();
318 } 327 }
319 InputMethodBase::OnTextInputTypeChanged(client); 328 InputMethodBase::OnTextInputTypeChanged(client);
320 } 329 }
321 330
322 void InputMethodIBus::OnCaretBoundsChanged(const TextInputClient* client) { 331 void InputMethodIBus::OnCaretBoundsChanged(const TextInputClient* client) {
323 if (!context_focused_ || !IsTextInputClientFocused(client)) 332 if (!context_focused_ || !IsTextInputClientFocused(client))
324 return; 333 return;
325 334
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // focus and after it acquires focus again are the same. 377 // focus and after it acquires focus again are the same.
369 OnTextInputTypeChanged(focused); 378 OnTextInputTypeChanged(focused);
370 379
371 UpdateContextFocusState(); 380 UpdateContextFocusState();
372 // Force to update caret bounds, in case the client thinks that the caret 381 // Force to update caret bounds, in case the client thinks that the caret
373 // bounds has not changed. 382 // bounds has not changed.
374 OnCaretBoundsChanged(focused); 383 OnCaretBoundsChanged(focused);
375 } 384 }
376 385
377 void InputMethodIBus::CreateContext() { 386 void InputMethodIBus::CreateContext() {
378 DCHECK(ibus_client_->IsConnected()); 387 DCHECK(IsConnected());
379 DCHECK(!pending_create_ic_request_); 388 DCHECK(!pending_create_ic_request_);
380 389
390 pending_create_ic_request_ = new PendingCreateICRequest(
391 this, &pending_create_ic_request_);
392
381 // Creates the input context asynchronously. 393 // Creates the input context asynchronously.
382 pending_create_ic_request_ = new PendingCreateICRequestImpl( 394 chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
383 this, ibus_client_.get(), &pending_create_ic_request_); 395 kClientName,
384 ibus_client_->CreateContext(pending_create_ic_request_); 396 base::Bind(&InputMethodIBus::CreateInputContextDone,
397 weak_ptr_factory_.GetWeakPtr(),
398 base::Unretained(pending_create_ic_request_)),
399 base::Bind(&InputMethodIBus::CreateInputContextFail,
400 weak_ptr_factory_.GetWeakPtr(),
401 base::Unretained(pending_create_ic_request_)));
385 } 402 }
386 403
387 void InputMethodIBus::SetUpSignalHandlers() { 404 void InputMethodIBus::SetUpSignalHandlers() {
388 DCHECK(ibus_client_->IsContextReady()); 405 DCHECK(IsContextReady());
389 406
390 // connect input context signals 407 // connect input context signals
391 chromeos::IBusInputContextClient* input_context_client = 408 chromeos::IBusInputContextClient* input_context_client =
392 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); 409 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
393 input_context_client->SetCommitTextHandler( 410 input_context_client->SetCommitTextHandler(
394 base::Bind(&InputMethodIBus::OnCommitText, 411 base::Bind(&InputMethodIBus::OnCommitText,
395 weak_ptr_factory_.GetWeakPtr())); 412 weak_ptr_factory_.GetWeakPtr()));
396 413
397 input_context_client->SetForwardKeyEventHandler( 414 input_context_client->SetForwardKeyEventHandler(
398 base::Bind(&InputMethodIBus::OnForwardKeyEvent, 415 base::Bind(&InputMethodIBus::OnForwardKeyEvent,
399 weak_ptr_factory_.GetWeakPtr())); 416 weak_ptr_factory_.GetWeakPtr()));
400 417
401 input_context_client->SetUpdatePreeditTextHandler( 418 input_context_client->SetUpdatePreeditTextHandler(
402 base::Bind(&InputMethodIBus::OnUpdatePreeditText, 419 base::Bind(&InputMethodIBus::OnUpdatePreeditText,
403 weak_ptr_factory_.GetWeakPtr())); 420 weak_ptr_factory_.GetWeakPtr()));
404 421
405 input_context_client->SetShowPreeditTextHandler( 422 input_context_client->SetShowPreeditTextHandler(
406 base::Bind(&InputMethodIBus::OnShowPreeditText, 423 base::Bind(&InputMethodIBus::OnShowPreeditText,
407 weak_ptr_factory_.GetWeakPtr())); 424 weak_ptr_factory_.GetWeakPtr()));
408 425
409 input_context_client->SetHidePreeditTextHandler( 426 input_context_client->SetHidePreeditTextHandler(
410 base::Bind(&InputMethodIBus::OnHidePreeditText, 427 base::Bind(&InputMethodIBus::OnHidePreeditText,
411 weak_ptr_factory_.GetWeakPtr())); 428 weak_ptr_factory_.GetWeakPtr()));
412 429
413 ibus_client_->SetCapabilities(internal::IBusClient::INLINE_COMPOSITION); 430 GetInputContextClient()->SetCapabilities(
431 kIBusCapabilityPreeditText | kIBusCapabilityFocus);
414 432
415 UpdateContextFocusState(); 433 UpdateContextFocusState();
416 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or 434 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or
417 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To 435 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To
418 // save the case, call OnCaretBoundsChanged() here. 436 // save the case, call OnCaretBoundsChanged() here.
419 OnCaretBoundsChanged(GetTextInputClient()); 437 OnCaretBoundsChanged(GetTextInputClient());
420 OnInputMethodChanged(); 438 OnInputMethodChanged();
421 } 439 }
422 440
423 void InputMethodIBus::DestroyContext() { 441 void InputMethodIBus::DestroyContext() {
424 if (pending_create_ic_request_) { 442 if (pending_create_ic_request_) {
425 DCHECK(!ibus_client_->IsContextReady()); 443 DCHECK(!IsContextReady());
426 // |pending_create_ic_request_| will be deleted in CreateInputContextDone(). 444 // |pending_create_ic_request_| will be deleted in CreateInputContextDone().
427 pending_create_ic_request_->Abandon(); 445 pending_create_ic_request_->Abandon();
428 pending_create_ic_request_ = NULL; 446 pending_create_ic_request_ = NULL;
429 return; 447 return;
430 } 448 }
431 const chromeos::IBusInputContextClient* input_context = 449 const chromeos::IBusInputContextClient* input_context =
432 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); 450 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
433 if (input_context && input_context->IsObjectProxyReady()) { 451 if (input_context && input_context->IsObjectProxyReady()) {
434 // We can't use IsContextReady here because we want to destroy object proxy 452 // We can't use IsContextReady here because we want to destroy object proxy
435 // regardless of connection. The IsContextReady contains connection check. 453 // regardless of connection. The IsContextReady contains connection check.
436 ResetInputContext(); 454 ResetInputContext();
437 DCHECK(!ibus_client_->IsContextReady()); 455 DCHECK(!IsContextReady());
438 } 456 }
439 } 457 }
440 458
441 void InputMethodIBus::ConfirmCompositionText() { 459 void InputMethodIBus::ConfirmCompositionText() {
442 TextInputClient* client = GetTextInputClient(); 460 TextInputClient* client = GetTextInputClient();
443 if (client && client->HasCompositionText()) 461 if (client && client->HasCompositionText())
444 client->ConfirmCompositionText(); 462 client->ConfirmCompositionText();
445 463
446 ResetContext(); 464 ResetContext();
447 } 465 }
(...skipping 21 matching lines...) Expand all
469 487
470 // We need to abandon all pending key events, but as above comment says, there 488 // We need to abandon all pending key events, but as above comment says, there
471 // is no reliable way to abandon all results generated by these abandoned key 489 // is no reliable way to abandon all results generated by these abandoned key
472 // events. 490 // events.
473 AbandonAllPendingKeyEvents(); 491 AbandonAllPendingKeyEvents();
474 492
475 // This function runs asynchronously. 493 // This function runs asynchronously.
476 // Note: some input method engines may not support reset method, such as 494 // Note: some input method engines may not support reset method, such as
477 // ibus-anthy. But as we control all input method engines by ourselves, we can 495 // ibus-anthy. But as we control all input method engines by ourselves, we can
478 // make sure that all of the engines we are using support it correctly. 496 // make sure that all of the engines we are using support it correctly.
479 ibus_client_->Reset(); 497 GetInputContextClient()->Reset();
480 498
481 character_composer_.Reset(); 499 character_composer_.Reset();
482 } 500 }
483 501
484 void InputMethodIBus::UpdateContextFocusState() { 502 void InputMethodIBus::UpdateContextFocusState() {
485 if (!ibus_client_->IsContextReady()) { 503 if (!IsContextReady()) {
486 context_focused_ = false; 504 context_focused_ = false;
487 return; 505 return;
488 } 506 }
489 507
490 const bool old_context_focused = context_focused_; 508 const bool old_context_focused = context_focused_;
491 // Use switch here in case we are going to add more text input types. 509 // Use switch here in case we are going to add more text input types.
492 switch (GetTextInputType()) { 510 switch (GetTextInputType()) {
493 case TEXT_INPUT_TYPE_NONE: 511 case TEXT_INPUT_TYPE_NONE:
494 case TEXT_INPUT_TYPE_PASSWORD: 512 case TEXT_INPUT_TYPE_PASSWORD:
495 context_focused_ = false; 513 context_focused_ = false;
496 break; 514 break;
497 default: 515 default:
498 context_focused_ = true; 516 context_focused_ = true;
499 break; 517 break;
500 } 518 }
501 519
502 // We only focus in |context_| when the focus is in a normal textfield. 520 // We only focus in |context_| when the focus is in a normal textfield.
503 // ibus_input_context_focus_{in|out}() run asynchronously. 521 // ibus_input_context_focus_{in|out}() run asynchronously.
504 if (old_context_focused && !context_focused_) 522 if (old_context_focused && !context_focused_)
505 ibus_client_->FocusOut(); 523 GetInputContextClient()->FocusOut();
506 else if (!old_context_focused && context_focused_) 524 else if (!old_context_focused && context_focused_)
507 ibus_client_->FocusIn(); 525 GetInputContextClient()->FocusIn();
508 526
509 if (context_focused_) { 527 if (context_focused_) {
510 internal::IBusClient::InlineCompositionCapability capability = 528 uint32 capability = kIBusCapabilityFocus;
511 CanComposeInline() ? internal::IBusClient::INLINE_COMPOSITION 529 if (CanComposeInline())
512 : internal::IBusClient::OFF_THE_SPOT_COMPOSITION; 530 capability |= kIBusCapabilityPreeditText;
513 ibus_client_->SetCapabilities(capability); 531 GetInputContextClient()->SetCapabilities(capability);
514 } 532 }
515 } 533 }
516 534
517 void InputMethodIBus::ProcessKeyEventPostIME( 535 void InputMethodIBus::ProcessKeyEventPostIME(
518 const base::NativeEvent& native_event, 536 const base::NativeEvent& native_event,
519 uint32 ibus_keyval, 537 uint32 ibus_keyval,
520 bool handled) { 538 bool handled) {
521 TextInputClient* client = GetTextInputClient(); 539 TextInputClient* client = GetTextInputClient();
522 540
523 if (!client) { 541 if (!client) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 bool InputMethodIBus::HasInputMethodResult() const { 718 bool InputMethodIBus::HasInputMethodResult() const {
701 return result_text_.length() || composition_changed_; 719 return result_text_.length() || composition_changed_;
702 } 720 }
703 721
704 void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const { 722 void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const {
705 DispatchFabricatedKeyEventPostIME(pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED, 723 DispatchFabricatedKeyEventPostIME(pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED,
706 VKEY_PROCESSKEY, 724 VKEY_PROCESSKEY,
707 0); 725 0);
708 } 726 }
709 727
710 void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEventImpl* pending_key) { 728 void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEvent* pending_key) {
711 DCHECK(pending_key_events_.count(pending_key)); 729 DCHECK(pending_key_events_.count(pending_key));
712 730
713 // |pending_key| will be deleted in ProcessKeyEventDone(). 731 // |pending_key| will be deleted in ProcessKeyEventDone().
714 pending_key_events_.erase(pending_key); 732 pending_key_events_.erase(pending_key);
715 } 733 }
716 734
717 void InputMethodIBus::AbandonAllPendingKeyEvents() { 735 void InputMethodIBus::AbandonAllPendingKeyEvents() {
718 std::set<PendingKeyEventImpl*>::iterator i; 736 std::set<PendingKeyEvent*>::iterator i;
719 for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) { 737 for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) {
720 // The object will be deleted in ProcessKeyEventDone(). 738 // The object will be deleted in ProcessKeyEventDone().
721 (*i)->Abandon(); 739 (*i)->Abandon();
722 } 740 }
723 pending_key_events_.clear(); 741 pending_key_events_.clear();
724 } 742 }
725 743
726 void InputMethodIBus::OnCommitText(const chromeos::ibus::IBusText& text) { 744 void InputMethodIBus::OnCommitText(const chromeos::ibus::IBusText& text) {
727 if (suppress_next_result_ || text.text().empty()) 745 if (suppress_next_result_ || text.text().empty())
728 return; 746 return;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 } 856 }
839 } 857 }
840 858
841 void InputMethodIBus::ResetInputContext() { 859 void InputMethodIBus::ResetInputContext() {
842 context_focused_ = false; 860 context_focused_ = false;
843 861
844 ConfirmCompositionText(); 862 ConfirmCompositionText();
845 863
846 // We are dead, so we need to ask the client to stop relying on us. 864 // We are dead, so we need to ask the client to stop relying on us.
847 OnInputMethodChanged(); 865 OnInputMethodChanged();
848 ibus_client_->DestroyProxy(); 866 GetInputContextClient()->ResetObjectProxy();
867 }
868
869 void InputMethodIBus::CreateInputContextDone(
870 PendingCreateICRequest* ic_request,
871 const dbus::ObjectPath& object_path) {
872 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
873 ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(),
874 object_path);
875 ic_request->InitOrAbandonInputContext();
876 delete ic_request;
877 }
878
879 void InputMethodIBus::CreateInputContextFail(
880 PendingCreateICRequest* ic_request) {
881 ic_request->OnCreateInputContextFailed();
882 delete ic_request;
883 }
884
885 bool InputMethodIBus::IsConnected() {
886 return chromeos::DBusThreadManager::Get()->GetIBusBus() != NULL;
887 }
888
889 bool InputMethodIBus::IsContextReady() {
890 if (!IsConnected())
891 return false;
892 if (!GetInputContextClient())
893 return false;
894 return GetInputContextClient()->IsObjectProxyReady();
849 } 895 }
850 896
851 void InputMethodIBus::OnConnected() { 897 void InputMethodIBus::OnConnected() {
852 DCHECK(ibus_client_->IsConnected()); 898 DCHECK(IsConnected());
853 // If already input context is initialized, do nothing. 899 // If already input context is initialized, do nothing.
854 if (ibus_client_->IsContextReady()) 900 if (IsContextReady())
855 return; 901 return;
856 902
857 DestroyContext(); 903 DestroyContext();
858 CreateContext(); 904 CreateContext();
859 } 905 }
860 906
861 void InputMethodIBus::OnDisconnected() { 907 void InputMethodIBus::OnDisconnected() {
862 DestroyContext(); 908 DestroyContext();
863 } 909 }
864 910
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 } 987 }
942 988
943 // Use a black thin underline by default. 989 // Use a black thin underline by default.
944 if (out_composition->underlines.empty()) { 990 if (out_composition->underlines.empty()) {
945 out_composition->underlines.push_back(CompositionUnderline( 991 out_composition->underlines.push_back(CompositionUnderline(
946 0, length, SK_ColorBLACK, false /* thick */)); 992 0, length, SK_ColorBLACK, false /* thick */));
947 } 993 }
948 } 994 }
949 995
950 } // namespace ui 996 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/ime/input_method_ibus.h ('k') | ui/base/ime/input_method_ibus_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698