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

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: Cl for review 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
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 chromeos::IBusInputContextClient* client =
89 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
90 DCHECK(client->IsConnected());
91 return client;
92 }
93
80 } // namespace 94 } // namespace
81 95
82 namespace ui { 96 namespace ui {
83 97
84 // InputMethodIBus::PendingKeyEventImpl implementation ------------------------ 98 // A class to hold all data related to a key event being processed by the input
85 class InputMethodIBus::PendingKeyEventImpl 99 // method but still has no result back yet.
86 : public internal::IBusClient::PendingKeyEvent { 100 class InputMethodIBus::PendingKeyEvent {
87 public: 101 public:
88 PendingKeyEventImpl(InputMethodIBus* input_method, 102 PendingKeyEvent(InputMethodIBus* input_method,
89 const base::NativeEvent& native_event, 103 const base::NativeEvent& native_event,
90 uint32 ibus_keyval); 104 uint32 ibus_keyval);
91 virtual ~PendingKeyEventImpl(); 105 virtual ~PendingKeyEvent();
92 106
93 // internal::IBusClient::PendingKeyEvent overrides: 107 // Process this pending key event after we receive its result from the input
94 virtual void ProcessPostIME(bool handled) OVERRIDE; 108 // method. It just call through InputMethodIBus::ProcessKeyEventPostIME().
109 void ProcessPostIME(bool handled);
95 110
96 // Abandon this pending key event. Its result will just be discarded. 111 // Abandon this pending key event. Its result will just be discarded.
97 void Abandon() { input_method_ = NULL; } 112 void Abandon() { input_method_ = NULL; }
98 113
99 InputMethodIBus* input_method() const { return input_method_; } 114 InputMethodIBus* input_method() const { return input_method_; }
100 115
101 private: 116 private:
102 InputMethodIBus* input_method_; 117 InputMethodIBus* input_method_;
103 118
104 // TODO(yusukes): To support a fabricated key event (which is typically from 119 // 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 120 // a virtual keyboard), we might have to copy event type, event flags, key
106 // code, 'character_', and 'unmodified_character_'. See views::InputMethodIBus 121 // code, 'character_', and 'unmodified_character_'. See views::InputMethodIBus
107 // for details. 122 // for details.
108 123
109 // corresponding XEvent data of a key event. It's a plain struct so we can do 124 // corresponding XEvent data of a key event. It's a plain struct so we can do
110 // bitwise copy. 125 // bitwise copy.
111 XKeyEvent x_event_; 126 XKeyEvent x_event_;
112 127
113 const uint32 ibus_keyval_; 128 const uint32 ibus_keyval_;
114 129
115 DISALLOW_COPY_AND_ASSIGN(PendingKeyEventImpl); 130 DISALLOW_COPY_AND_ASSIGN(PendingKeyEvent);
116 }; 131 };
117 132
118 InputMethodIBus::PendingKeyEventImpl::PendingKeyEventImpl( 133 InputMethodIBus::PendingKeyEvent::PendingKeyEvent(
119 InputMethodIBus* input_method, 134 InputMethodIBus* input_method,
120 const base::NativeEvent& native_event, 135 const base::NativeEvent& native_event,
121 uint32 ibus_keyval) 136 uint32 ibus_keyval)
122 : input_method_(input_method), 137 : input_method_(input_method),
123 ibus_keyval_(ibus_keyval) { 138 ibus_keyval_(ibus_keyval) {
124 DCHECK(input_method_); 139 DCHECK(input_method_);
125 140
126 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). 141 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard).
127 DCHECK(native_event); 142 DCHECK(native_event);
128 x_event_ = *GetKeyEvent(native_event); 143 x_event_ = *GetKeyEvent(native_event);
129 } 144 }
130 145
131 InputMethodIBus::PendingKeyEventImpl::~PendingKeyEventImpl() { 146 InputMethodIBus::PendingKeyEvent::~PendingKeyEvent() {
132 if (input_method_) 147 if (input_method_)
133 input_method_->FinishPendingKeyEvent(this); 148 input_method_->FinishPendingKeyEvent(this);
134 } 149 }
135 150
136 void InputMethodIBus::PendingKeyEventImpl::ProcessPostIME(bool handled) { 151 void InputMethodIBus::PendingKeyEvent::ProcessPostIME(bool handled) {
137 if (!input_method_) 152 if (!input_method_)
138 return; 153 return;
139 154
140 if (x_event_.type == KeyPress || x_event_.type == KeyRelease) { 155 if (x_event_.type == KeyPress || x_event_.type == KeyRelease) {
141 input_method_->ProcessKeyEventPostIME(reinterpret_cast<XEvent*>(&x_event_), 156 input_method_->ProcessKeyEventPostIME(reinterpret_cast<XEvent*>(&x_event_),
142 ibus_keyval_, 157 ibus_keyval_,
143 handled); 158 handled);
144 return; 159 return;
145 } 160 }
146 161
147 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). 162 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard).
148 // See views::InputMethodIBus for details. Never forget to set 'character_' 163 // See views::InputMethodIBus for details. Never forget to set 'character_'
149 // and 'unmodified_character_' to support i18n VKs like a French VK! 164 // and 'unmodified_character_' to support i18n VKs like a French VK!
150 } 165 }
151 166
152 // InputMethodIBus::PendingCreateICRequestImpl implementation ----------------- 167 // A class to hold information of a pending request for creating an ibus input
153 class InputMethodIBus::PendingCreateICRequestImpl 168 // context.
154 : public internal::IBusClient::PendingCreateICRequest { 169 class InputMethodIBus::PendingCreateICRequest {
155 public: 170 public:
156 PendingCreateICRequestImpl(InputMethodIBus* input_method, 171 PendingCreateICRequest(InputMethodIBus* input_method,
157 internal::IBusClient* ibus_client, 172 PendingCreateICRequest** request_ptr);
158 PendingCreateICRequestImpl** request_ptr); 173 virtual ~PendingCreateICRequest();
159 virtual ~PendingCreateICRequestImpl();
160 174
161 // internal::IBusClient::PendingCreateICRequest overrides: 175 // Set up signal handlers, or destroy object proxy if the input context is
162 virtual void InitOrAbandonInputContext() OVERRIDE; 176 // already abandoned.
163 virtual void OnCreateInputContextFailed() OVERRIDE; 177 void InitOrAbandonInputContext();
178
179 // Called if the create input context method call is failed.
180 void OnCreateInputContextFailed();
164 181
165 // Abandon this pending key event. Its result will just be discarded. 182 // Abandon this pending key event. Its result will just be discarded.
166 void Abandon() { 183 void Abandon() {
167 input_method_ = NULL; 184 input_method_ = NULL;
168 request_ptr_ = NULL; 185 request_ptr_ = NULL;
169 // Do not reset |ibus_client_| here. 186 // Do not reset |ibus_client_| here.
170 } 187 }
171 188
172 private: 189 private:
173 InputMethodIBus* input_method_; 190 InputMethodIBus* input_method_;
174 internal::IBusClient* ibus_client_; 191 PendingCreateICRequest** request_ptr_;
175 PendingCreateICRequestImpl** request_ptr_;
176 192
177 DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequestImpl); 193 DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequest);
178 }; 194 };
179 195
180 InputMethodIBus::PendingCreateICRequestImpl::PendingCreateICRequestImpl( 196 InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest(
181 InputMethodIBus* input_method, 197 InputMethodIBus* input_method,
182 internal::IBusClient* ibus_client, 198 PendingCreateICRequest** request_ptr)
183 PendingCreateICRequestImpl** request_ptr)
184 : input_method_(input_method), 199 : input_method_(input_method),
185 ibus_client_(ibus_client),
186 request_ptr_(request_ptr) { 200 request_ptr_(request_ptr) {
187 } 201 }
188 202
189 InputMethodIBus::PendingCreateICRequestImpl::~PendingCreateICRequestImpl() { 203 InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() {
190 if (request_ptr_) { 204 if (request_ptr_) {
191 DCHECK_EQ(*request_ptr_, this); 205 DCHECK_EQ(*request_ptr_, this);
192 *request_ptr_ = NULL; 206 *request_ptr_ = NULL;
193 } 207 }
194 } 208 }
195 209
196 void InputMethodIBus::PendingCreateICRequestImpl::OnCreateInputContextFailed() { 210 void InputMethodIBus::PendingCreateICRequest::OnCreateInputContextFailed() {
197 // TODO(nona): If the connection between Chrome and ibus-daemon terminates 211 // 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 212 // for some reason, the create ic request will fail. We might want to call
199 // ibus_client_->CreateContext() again after some delay. 213 // ibus_client_->CreateContext() again after some delay.
200 } 214 }
201 215
202 void InputMethodIBus::PendingCreateICRequestImpl::InitOrAbandonInputContext() { 216 void InputMethodIBus::PendingCreateICRequest::InitOrAbandonInputContext() {
203 if (input_method_) { 217 if (input_method_) {
204 DCHECK(ibus_client_->IsContextReady()); 218 DCHECK(input_method_->IsContextReady());
205 input_method_->SetUpSignalHandlers(); 219 input_method_->SetUpSignalHandlers();
206 } else { 220 } else {
207 ibus_client_->DestroyProxy(); 221 GetInputContextClient()->ResetObjectProxy();
208 DCHECK(!ibus_client_->IsContextReady());
209 } 222 }
210 } 223 }
211 224
212 // InputMethodIBus implementation ----------------------------------------- 225 // InputMethodIBus implementation -----------------------------------------
213 InputMethodIBus::InputMethodIBus( 226 InputMethodIBus::InputMethodIBus(
214 internal::InputMethodDelegate* delegate) 227 internal::InputMethodDelegate* delegate)
215 : 228 : ibus_client_(new internal::IBusClient()),
Yusuke Sato 2012/06/25 13:41:33 omit () for style consistency
Seigo Nonaka 2012/06/28 03:43:03 Done.
216 ibus_client_(new internal::IBusClientImpl),
217 pending_create_ic_request_(NULL), 229 pending_create_ic_request_(NULL),
218 context_focused_(false), 230 context_focused_(false),
219 composing_text_(false), 231 composing_text_(false),
220 composition_changed_(false), 232 composition_changed_(false),
221 suppress_next_result_(false), 233 suppress_next_result_(false),
222 weak_ptr_factory_(this) { 234 weak_ptr_factory_(this) {
223 SetDelegate(delegate); 235 SetDelegate(delegate);
224 } 236 }
225 237
226 InputMethodIBus::~InputMethodIBus() { 238 InputMethodIBus::~InputMethodIBus() {
(...skipping 20 matching lines...) Expand all
247 InputMethodBase::OnBlur(); 259 InputMethodBase::OnBlur();
248 UpdateContextFocusState(); 260 UpdateContextFocusState();
249 } 261 }
250 262
251 void InputMethodIBus::Init(bool focused) { 263 void InputMethodIBus::Init(bool focused) {
252 // Initializes the connection to ibus daemon. It may happen asynchronously, 264 // Initializes the connection to ibus daemon. It may happen asynchronously,
253 // and as soon as the connection is established, the |context_| will be 265 // and as soon as the connection is established, the |context_| will be
254 // created automatically. 266 // created automatically.
255 267
256 // Create the input context if the connection is already established. 268 // Create the input context if the connection is already established.
257 if (ibus_client_->IsConnected()) 269 if (IsConnected())
258 CreateContext(); 270 CreateContext();
259 271
260 InputMethodBase::Init(focused); 272 InputMethodBase::Init(focused);
261 } 273 }
262 274
263 // static 275 // static
264 void InputMethodIBus::ProcessKeyEventDone( 276 void InputMethodIBus::ProcessKeyEventDone(
265 PendingKeyEventImpl* pending_key_event, bool is_handled) { 277 PendingKeyEvent* pending_key_event, bool is_handled) {
266 DCHECK(pending_key_event); 278 DCHECK(pending_key_event);
267 pending_key_event->ProcessPostIME(is_handled); 279 pending_key_event->ProcessPostIME(is_handled);
268 delete pending_key_event; 280 delete pending_key_event;
269 } 281 }
270 282
271 void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) { 283 void InputMethodIBus::DispatchKeyEvent(const base::NativeEvent& native_event) {
272 DCHECK(native_event && (native_event->type == KeyPress || 284 DCHECK(native_event && (native_event->type == KeyPress ||
273 native_event->type == KeyRelease)); 285 native_event->type == KeyRelease));
274 DCHECK(system_toplevel_window_focused()); 286 DCHECK(system_toplevel_window_focused());
275 287
(...skipping 12 matching lines...) Expand all
288 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD || 300 GetTextInputType() == TEXT_INPUT_TYPE_PASSWORD ||
289 ibus_client_->GetInputMethodType() == 301 ibus_client_->GetInputMethodType() ==
290 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) { 302 internal::IBusClient::INPUT_METHOD_XKB_LAYOUT) {
291 if (native_event->type == KeyPress) 303 if (native_event->type == KeyPress)
292 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval); 304 ProcessUnfilteredKeyPressEvent(native_event, ibus_keyval);
293 else 305 else
294 DispatchKeyEventPostIME(native_event); 306 DispatchKeyEventPostIME(native_event);
295 return; 307 return;
296 } 308 }
297 309
298 PendingKeyEventImpl* pending_key = 310 PendingKeyEvent* pending_key =
299 new PendingKeyEventImpl(this, native_event, ibus_keyval); 311 new PendingKeyEvent(this, native_event, ibus_keyval);
300 pending_key_events_.insert(pending_key); 312 pending_key_events_.insert(pending_key);
301 313
302 ibus_client_->SendKeyEvent(ibus_keyval, 314 GetInputContextClient()->ProcessKeyEvent(
303 ibus_keycode, 315 ibus_keyval,
304 ibus_state, 316 ibus_keycode,
305 base::Bind(&InputMethodIBus::ProcessKeyEventDone, 317 ibus_state, base::Bind(&InputMethodIBus::ProcessKeyEventDone,
306 base::Unretained(pending_key))); 318 base::Unretained(pending_key)));
307 319
308 // We don't want to suppress the result generated by this key event, but it 320 // We don't want to suppress the result generated by this key event, but it
309 // may cause problem. See comment in ResetContext() method. 321 // may cause problem. See comment in ResetContext() method.
310 suppress_next_result_ = false; 322 suppress_next_result_ = false;
311 } 323 }
312 324
313 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) { 325 void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) {
314 if (ibus_client_->IsContextReady() && IsTextInputClientFocused(client)) { 326 if (IsContextReady() && IsTextInputClientFocused(client)) {
315 ResetContext(); 327 ResetContext();
316 UpdateContextFocusState(); 328 UpdateContextFocusState();
317 } 329 }
318 InputMethodBase::OnTextInputTypeChanged(client); 330 InputMethodBase::OnTextInputTypeChanged(client);
319 } 331 }
320 332
321 void InputMethodIBus::OnCaretBoundsChanged(const TextInputClient* client) { 333 void InputMethodIBus::OnCaretBoundsChanged(const TextInputClient* client) {
322 if (!context_focused_ || !IsTextInputClientFocused(client)) 334 if (!context_focused_ || !IsTextInputClientFocused(client))
323 return; 335 return;
324 336
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // focus and after it acquires focus again are the same. 379 // focus and after it acquires focus again are the same.
368 OnTextInputTypeChanged(focused); 380 OnTextInputTypeChanged(focused);
369 381
370 UpdateContextFocusState(); 382 UpdateContextFocusState();
371 // Force to update caret bounds, in case the client thinks that the caret 383 // Force to update caret bounds, in case the client thinks that the caret
372 // bounds has not changed. 384 // bounds has not changed.
373 OnCaretBoundsChanged(focused); 385 OnCaretBoundsChanged(focused);
374 } 386 }
375 387
376 void InputMethodIBus::CreateContext() { 388 void InputMethodIBus::CreateContext() {
377 DCHECK(ibus_client_->IsConnected()); 389 DCHECK(IsConnected());
378 DCHECK(!pending_create_ic_request_); 390 DCHECK(!pending_create_ic_request_);
379 391
392 pending_create_ic_request_ = new PendingCreateICRequest(
393 this, &pending_create_ic_request_);
394
380 // Creates the input context asynchronously. 395 // Creates the input context asynchronously.
381 pending_create_ic_request_ = new PendingCreateICRequestImpl( 396 chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
382 this, ibus_client_.get(), &pending_create_ic_request_); 397 kClientName,
383 ibus_client_->CreateContext(pending_create_ic_request_); 398 base::Bind(&InputMethodIBus::CreateInputContextDone,
399 weak_ptr_factory_.GetWeakPtr(),
400 base::Unretained(pending_create_ic_request_)),
401 base::Bind(&InputMethodIBus::CreateInputContextFail,
402 weak_ptr_factory_.GetWeakPtr(),
403 base::Unretained(pending_create_ic_request_)));
384 } 404 }
385 405
386 void InputMethodIBus::SetUpSignalHandlers() { 406 void InputMethodIBus::SetUpSignalHandlers() {
387 DCHECK(ibus_client_->IsContextReady()); 407 DCHECK(IsContextReady());
388 408
389 // connect input context signals 409 // connect input context signals
390 chromeos::IBusInputContextClient* input_context_client = 410 chromeos::IBusInputContextClient* input_context_client =
391 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); 411 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
392 input_context_client->SetCommitTextHandler( 412 input_context_client->SetCommitTextHandler(
393 base::Bind(&InputMethodIBus::OnCommitText, 413 base::Bind(&InputMethodIBus::OnCommitText,
394 weak_ptr_factory_.GetWeakPtr())); 414 weak_ptr_factory_.GetWeakPtr()));
395 415
396 input_context_client->SetForwardKeyEventHandler( 416 input_context_client->SetForwardKeyEventHandler(
397 base::Bind(&InputMethodIBus::OnForwardKeyEvent, 417 base::Bind(&InputMethodIBus::OnForwardKeyEvent,
398 weak_ptr_factory_.GetWeakPtr())); 418 weak_ptr_factory_.GetWeakPtr()));
399 419
400 input_context_client->SetUpdatePreeditTextHandler( 420 input_context_client->SetUpdatePreeditTextHandler(
401 base::Bind(&InputMethodIBus::OnUpdatePreeditText, 421 base::Bind(&InputMethodIBus::OnUpdatePreeditText,
402 weak_ptr_factory_.GetWeakPtr())); 422 weak_ptr_factory_.GetWeakPtr()));
403 423
404 input_context_client->SetShowPreeditTextHandler( 424 input_context_client->SetShowPreeditTextHandler(
405 base::Bind(&InputMethodIBus::OnShowPreeditText, 425 base::Bind(&InputMethodIBus::OnShowPreeditText,
406 weak_ptr_factory_.GetWeakPtr())); 426 weak_ptr_factory_.GetWeakPtr()));
407 427
408 input_context_client->SetHidePreeditTextHandler( 428 input_context_client->SetHidePreeditTextHandler(
409 base::Bind(&InputMethodIBus::OnHidePreeditText, 429 base::Bind(&InputMethodIBus::OnHidePreeditText,
410 weak_ptr_factory_.GetWeakPtr())); 430 weak_ptr_factory_.GetWeakPtr()));
411 431
412 ibus_client_->SetCapabilities(internal::IBusClient::INLINE_COMPOSITION); 432 GetInputContextClient()->SetCapabilities(
433 kIBusCapabilityPreeditText | kIBusCapabilityFocus);
413 434
414 UpdateContextFocusState(); 435 UpdateContextFocusState();
415 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or 436 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or
416 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To 437 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To
417 // save the case, call OnCaretBoundsChanged() here. 438 // save the case, call OnCaretBoundsChanged() here.
418 OnCaretBoundsChanged(GetTextInputClient()); 439 OnCaretBoundsChanged(GetTextInputClient());
419 OnInputMethodChanged(); 440 OnInputMethodChanged();
420 } 441 }
421 442
422 void InputMethodIBus::DestroyContext() { 443 void InputMethodIBus::DestroyContext() {
423 if (pending_create_ic_request_) { 444 if (pending_create_ic_request_) {
424 DCHECK(!ibus_client_->IsContextReady()); 445 DCHECK(!IsContextReady());
425 // |pending_create_ic_request_| will be deleted in CreateInputContextDone(). 446 // |pending_create_ic_request_| will be deleted in CreateInputContextDone().
426 pending_create_ic_request_->Abandon(); 447 pending_create_ic_request_->Abandon();
427 pending_create_ic_request_ = NULL; 448 pending_create_ic_request_ = NULL;
428 } else if (chromeos::DBusThreadManager::Get()->GetIBusInputContextClient() 449 } else if (chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
429 ->IsConnected()) { 450 ->IsConnected()) {
430 // We can't use IsContextReady here because we want to destroy input context 451 // We can't use IsContextReady here because we want to destroy input context
431 // due to connection lost here and IsContextReady contains connection check. 452 // due to connection lost here and IsContextReady contains connection check.
432 ResetInputContext(); 453 ResetInputContext();
433 DCHECK(!ibus_client_->IsContextReady()); 454 DCHECK(!IsContextReady());
434 } 455 }
435 } 456 }
436 457
437 void InputMethodIBus::ConfirmCompositionText() { 458 void InputMethodIBus::ConfirmCompositionText() {
438 TextInputClient* client = GetTextInputClient(); 459 TextInputClient* client = GetTextInputClient();
439 if (client && client->HasCompositionText()) 460 if (client && client->HasCompositionText())
440 client->ConfirmCompositionText(); 461 client->ConfirmCompositionText();
441 462
442 ResetContext(); 463 ResetContext();
443 } 464 }
(...skipping 21 matching lines...) Expand all
465 486
466 // We need to abandon all pending key events, but as above comment says, there 487 // We need to abandon all pending key events, but as above comment says, there
467 // is no reliable way to abandon all results generated by these abandoned key 488 // is no reliable way to abandon all results generated by these abandoned key
468 // events. 489 // events.
469 AbandonAllPendingKeyEvents(); 490 AbandonAllPendingKeyEvents();
470 491
471 // This function runs asynchronously. 492 // This function runs asynchronously.
472 // Note: some input method engines may not support reset method, such as 493 // Note: some input method engines may not support reset method, such as
473 // ibus-anthy. But as we control all input method engines by ourselves, we can 494 // ibus-anthy. But as we control all input method engines by ourselves, we can
474 // make sure that all of the engines we are using support it correctly. 495 // make sure that all of the engines we are using support it correctly.
475 ibus_client_->Reset(); 496 GetInputContextClient()->Reset();
476 497
477 character_composer_.Reset(); 498 character_composer_.Reset();
478 } 499 }
479 500
480 void InputMethodIBus::UpdateContextFocusState() { 501 void InputMethodIBus::UpdateContextFocusState() {
481 if (!ibus_client_->IsContextReady()) { 502 if (!IsContextReady()) {
482 context_focused_ = false; 503 context_focused_ = false;
483 return; 504 return;
484 } 505 }
485 506
486 const bool old_context_focused = context_focused_; 507 const bool old_context_focused = context_focused_;
487 // Use switch here in case we are going to add more text input types. 508 // Use switch here in case we are going to add more text input types.
488 switch (GetTextInputType()) { 509 switch (GetTextInputType()) {
489 case TEXT_INPUT_TYPE_NONE: 510 case TEXT_INPUT_TYPE_NONE:
490 case TEXT_INPUT_TYPE_PASSWORD: 511 case TEXT_INPUT_TYPE_PASSWORD:
491 context_focused_ = false; 512 context_focused_ = false;
492 break; 513 break;
493 default: 514 default:
494 context_focused_ = true; 515 context_focused_ = true;
495 break; 516 break;
496 } 517 }
497 518
498 // We only focus in |context_| when the focus is in a normal textfield. 519 // We only focus in |context_| when the focus is in a normal textfield.
499 // ibus_input_context_focus_{in|out}() run asynchronously. 520 // ibus_input_context_focus_{in|out}() run asynchronously.
500 if (old_context_focused && !context_focused_) 521 if (old_context_focused && !context_focused_)
501 ibus_client_->FocusOut(); 522 GetInputContextClient()->FocusOut();
502 else if (!old_context_focused && context_focused_) 523 else if (!old_context_focused && context_focused_)
503 ibus_client_->FocusIn(); 524 GetInputContextClient()->FocusIn();
504 525
505 if (context_focused_) { 526 if (context_focused_) {
506 internal::IBusClient::InlineCompositionCapability capability = 527 uint32 capability = kIBusCapabilityFocus;
507 CanComposeInline() ? internal::IBusClient::INLINE_COMPOSITION 528 if (CanComposeInline())
508 : internal::IBusClient::OFF_THE_SPOT_COMPOSITION; 529 capability |= kIBusCapabilityPreeditText;
509 ibus_client_->SetCapabilities(capability); 530 GetInputContextClient()->SetCapabilities(capability);
510 } 531 }
511 } 532 }
512 533
513 void InputMethodIBus::ProcessKeyEventPostIME( 534 void InputMethodIBus::ProcessKeyEventPostIME(
514 const base::NativeEvent& native_event, 535 const base::NativeEvent& native_event,
515 uint32 ibus_keyval, 536 uint32 ibus_keyval,
516 bool handled) { 537 bool handled) {
517 TextInputClient* client = GetTextInputClient(); 538 TextInputClient* client = GetTextInputClient();
518 539
519 if (!client) { 540 if (!client) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 bool InputMethodIBus::HasInputMethodResult() const { 713 bool InputMethodIBus::HasInputMethodResult() const {
693 return result_text_.length() || composition_changed_; 714 return result_text_.length() || composition_changed_;
694 } 715 }
695 716
696 void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const { 717 void InputMethodIBus::SendFakeProcessKeyEvent(bool pressed) const {
697 DispatchFabricatedKeyEventPostIME(pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED, 718 DispatchFabricatedKeyEventPostIME(pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED,
698 VKEY_PROCESSKEY, 719 VKEY_PROCESSKEY,
699 0); 720 0);
700 } 721 }
701 722
702 void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEventImpl* pending_key) { 723 void InputMethodIBus::FinishPendingKeyEvent(PendingKeyEvent* pending_key) {
703 DCHECK(pending_key_events_.count(pending_key)); 724 DCHECK(pending_key_events_.count(pending_key));
704 725
705 // |pending_key| will be deleted in ProcessKeyEventDone(). 726 // |pending_key| will be deleted in ProcessKeyEventDone().
706 pending_key_events_.erase(pending_key); 727 pending_key_events_.erase(pending_key);
707 } 728 }
708 729
709 void InputMethodIBus::AbandonAllPendingKeyEvents() { 730 void InputMethodIBus::AbandonAllPendingKeyEvents() {
710 std::set<PendingKeyEventImpl*>::iterator i; 731 std::set<PendingKeyEvent*>::iterator i;
711 for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) { 732 for (i = pending_key_events_.begin(); i != pending_key_events_.end(); ++i) {
712 // The object will be deleted in ProcessKeyEventDone(). 733 // The object will be deleted in ProcessKeyEventDone().
713 (*i)->Abandon(); 734 (*i)->Abandon();
714 } 735 }
715 pending_key_events_.clear(); 736 pending_key_events_.clear();
716 } 737 }
717 738
718 void InputMethodIBus::OnCommitText(const chromeos::ibus::IBusText& text) { 739 void InputMethodIBus::OnCommitText(const chromeos::ibus::IBusText& text) {
719 if (suppress_next_result_ || text.text().empty()) 740 if (suppress_next_result_ || text.text().empty())
720 return; 741 return;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } 848 }
828 } 849 }
829 850
830 void InputMethodIBus::ResetInputContext() { 851 void InputMethodIBus::ResetInputContext() {
831 context_focused_ = false; 852 context_focused_ = false;
832 853
833 ConfirmCompositionText(); 854 ConfirmCompositionText();
834 855
835 // We are dead, so we need to ask the client to stop relying on us. 856 // We are dead, so we need to ask the client to stop relying on us.
836 OnInputMethodChanged(); 857 OnInputMethodChanged();
837 ibus_client_->DestroyProxy(); 858 GetInputContextClient()->ResetObjectProxy();
859 }
860
861 void InputMethodIBus::CreateInputContextDone(
862 PendingCreateICRequest* ic_request,
863 const dbus::ObjectPath& object_path) {
864 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
865 ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(),
866 object_path);
867 ic_request->InitOrAbandonInputContext();
868 delete ic_request;
869 }
870
871 void InputMethodIBus::CreateInputContextFail(
872 PendingCreateICRequest* ic_request) {
873 ic_request->OnCreateInputContextFailed();
874 delete ic_request;
875 }
876
877 bool InputMethodIBus::IsConnected() {
878 return chromeos::DBusThreadManager::Get()->GetIBusBus() != NULL;
879 }
880
881 bool InputMethodIBus::IsContextReady() {
882 return IsConnected() &&
883 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
884 ->IsConnected();
838 } 885 }
839 886
840 void InputMethodIBus::OnConnected() { 887 void InputMethodIBus::OnConnected() {
841 DCHECK(ibus_client_->IsConnected()); 888 DCHECK(IsConnected());
842 // If already input context is initialized, do nothing. 889 // If already input context is initialized, do nothing.
843 if (ibus_client_->IsContextReady()) 890 if (IsContextReady())
844 return; 891 return;
845 892
846 DestroyContext(); 893 DestroyContext();
847 CreateContext(); 894 CreateContext();
848 } 895 }
849 896
850 void InputMethodIBus::OnDisconnected() { 897 void InputMethodIBus::OnDisconnected() {
851 DestroyContext(); 898 DestroyContext();
852 } 899 }
853 900
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 } 977 }
931 978
932 // Use a black thin underline by default. 979 // Use a black thin underline by default.
933 if (out_composition->underlines.empty()) { 980 if (out_composition->underlines.empty()) {
934 out_composition->underlines.push_back(CompositionUnderline( 981 out_composition->underlines.push_back(CompositionUnderline(
935 0, length, SK_ColorBLACK, false /* thick */)); 982 0, length, SK_ColorBLACK, false /* thick */));
936 } 983 }
937 } 984 }
938 985
939 } // namespace ui 986 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698