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

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

Issue 10834175: Remove PendingCreateICRequest. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Address comments Created 8 years, 4 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
(...skipping 20 matching lines...) Expand all
31 #include "ui/base/ime/text_input_client.h" 31 #include "ui/base/ime/text_input_client.h"
32 #include "ui/base/keycodes/keyboard_code_conversion.h" 32 #include "ui/base/keycodes/keyboard_code_conversion.h"
33 #include "ui/base/keycodes/keyboard_code_conversion_x.h" 33 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
34 #include "ui/base/keycodes/keyboard_codes.h" 34 #include "ui/base/keycodes/keyboard_codes.h"
35 #include "ui/gfx/rect.h" 35 #include "ui/gfx/rect.h"
36 36
37 namespace { 37 namespace {
38 38
39 const int kIBusReleaseMask = 1 << 30; 39 const int kIBusReleaseMask = 1 << 30;
40 const char kClientName[] = "chrome"; 40 const char kClientName[] = "chrome";
41 const int kMaxRetryCount = 10;
41 42
42 // Following capability mask is introduced from 43 // Following capability mask is introduced from
43 // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabili te 44 // http://ibus.googlecode.com/svn/docs/ibus-1.4/ibus-ibustypes.html#IBusCapabili te
44 const uint32 kIBusCapabilityPreeditText = 1U; 45 const uint32 kIBusCapabilityPreeditText = 1U;
45 const uint32 kIBusCapabilityFocus = 8U; 46 const uint32 kIBusCapabilityFocus = 8U;
46 const uint32 kIBusCapabilitySurroundingText = 32U; 47 const uint32 kIBusCapabilitySurroundingText = 32U;
47 48
48 XKeyEvent* GetKeyEvent(XEvent* event) { 49 XKeyEvent* GetKeyEvent(XEvent* event) {
49 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease)); 50 DCHECK(event && (event->type == KeyPress || event->type == KeyRelease));
50 return &event->xkey; 51 return &event->xkey;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 ibus_keyval_, 156 ibus_keyval_,
156 handled); 157 handled);
157 return; 158 return;
158 } 159 }
159 160
160 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard). 161 // TODO(yusukes): Support non-native event (from e.g. a virtual keyboard).
161 // See views::InputMethodIBus for details. Never forget to set 'character_' 162 // See views::InputMethodIBus for details. Never forget to set 'character_'
162 // and 'unmodified_character_' to support i18n VKs like a French VK! 163 // and 'unmodified_character_' to support i18n VKs like a French VK!
163 } 164 }
164 165
165 // A class to hold information of a pending request for creating an ibus input
166 // context.
167 class InputMethodIBus::PendingCreateICRequest {
168 public:
169 PendingCreateICRequest(InputMethodIBus* input_method,
170 PendingCreateICRequest** request_ptr);
171 virtual ~PendingCreateICRequest();
172
173 // Set up signal handlers, or destroy object proxy if the input context is
174 // already abandoned.
175 void InitOrAbandonInputContext();
176
177 // Called if the create input context method call is failed.
178 void OnCreateInputContextFailed();
179
180 // Abandon this pending key event. Its result will just be discarded.
181 void Abandon() {
182 input_method_ = NULL;
183 request_ptr_ = NULL;
184 // Do not reset |ibus_client_| here.
185 }
186
187 private:
188 InputMethodIBus* input_method_;
189 PendingCreateICRequest** request_ptr_;
190
191 DISALLOW_COPY_AND_ASSIGN(PendingCreateICRequest);
192 };
193
194 InputMethodIBus::PendingCreateICRequest::PendingCreateICRequest(
195 InputMethodIBus* input_method,
196 PendingCreateICRequest** request_ptr)
197 : input_method_(input_method),
198 request_ptr_(request_ptr) {
199 }
200
201 InputMethodIBus::PendingCreateICRequest::~PendingCreateICRequest() {
202 if (request_ptr_) {
203 DCHECK_EQ(*request_ptr_, this);
204 *request_ptr_ = NULL;
205 }
206 }
207
208 void InputMethodIBus::PendingCreateICRequest::OnCreateInputContextFailed() {
209 // TODO(nona): If the connection between Chrome and ibus-daemon terminates
210 // for some reason, the create ic request will fail. We might want to call
211 // ibus_client_->CreateContext() again after some delay.
212 }
213
214 void InputMethodIBus::PendingCreateICRequest::InitOrAbandonInputContext() {
215 if (input_method_) {
216 DCHECK(input_method_->IsContextReady());
217 input_method_->SetUpSignalHandlers();
218 } else {
219 GetInputContextClient()->ResetObjectProxy();
220 }
221 }
222
223 // InputMethodIBus implementation ----------------------------------------- 166 // InputMethodIBus implementation -----------------------------------------
224 InputMethodIBus::InputMethodIBus( 167 InputMethodIBus::InputMethodIBus(
225 internal::InputMethodDelegate* delegate) 168 internal::InputMethodDelegate* delegate)
226 : ibus_client_(new internal::IBusClient), 169 : ibus_client_(new internal::IBusClient),
227 pending_create_ic_request_(NULL), 170 input_context_state_(INPUT_CONTEXT_STOP),
171 create_input_context_fail_count_(0),
228 context_focused_(false), 172 context_focused_(false),
229 composing_text_(false), 173 composing_text_(false),
230 composition_changed_(false), 174 composition_changed_(false),
231 suppress_next_result_(false), 175 suppress_next_result_(false),
232 weak_ptr_factory_(this) { 176 weak_ptr_factory_(this) {
233 SetDelegate(delegate); 177 SetDelegate(delegate);
234 } 178 }
235 179
236 InputMethodIBus::~InputMethodIBus() { 180 InputMethodIBus::~InputMethodIBus() {
237 AbandonAllPendingKeyEvents(); 181 AbandonAllPendingKeyEvents();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 OnTextInputTypeChanged(focused); 360 OnTextInputTypeChanged(focused);
417 361
418 UpdateContextFocusState(); 362 UpdateContextFocusState();
419 // Force to update caret bounds, in case the client thinks that the caret 363 // Force to update caret bounds, in case the client thinks that the caret
420 // bounds has not changed. 364 // bounds has not changed.
421 OnCaretBoundsChanged(focused); 365 OnCaretBoundsChanged(focused);
422 } 366 }
423 367
424 void InputMethodIBus::CreateContext() { 368 void InputMethodIBus::CreateContext() {
425 DCHECK(IsConnected()); 369 DCHECK(IsConnected());
426 DCHECK(!pending_create_ic_request_);
427 370
428 pending_create_ic_request_ = new PendingCreateICRequest( 371 if (input_context_state_ != INPUT_CONTEXT_STOP) {
429 this, &pending_create_ic_request_); 372 DVLOG(1) << "Input context is already created or waiting ibus-daemon"
373 " response.";
374 return;
375 }
376
377 input_context_state_ = INPUT_CONTEXT_WAIT_CREATE_INPUT_CONTEXT_RESPONSE;
430 378
431 // Creates the input context asynchronously. 379 // Creates the input context asynchronously.
380 DCHECK(!IsContextReady());
432 chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext( 381 chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
433 kClientName, 382 kClientName,
434 base::Bind(&InputMethodIBus::CreateInputContextDone, 383 base::Bind(&InputMethodIBus::CreateInputContextDone,
435 weak_ptr_factory_.GetWeakPtr(), 384 weak_ptr_factory_.GetWeakPtr()),
436 base::Unretained(pending_create_ic_request_)),
437 base::Bind(&InputMethodIBus::CreateInputContextFail, 385 base::Bind(&InputMethodIBus::CreateInputContextFail,
438 weak_ptr_factory_.GetWeakPtr(), 386 weak_ptr_factory_.GetWeakPtr()));
439 base::Unretained(pending_create_ic_request_)));
440 } 387 }
441 388
442 void InputMethodIBus::SetUpSignalHandlers() { 389 void InputMethodIBus::SetUpSignalHandlers() {
443 DCHECK(IsContextReady()); 390 DCHECK(IsContextReady());
444 391
445 // connect input context signals 392 // connect input context signals
446 chromeos::IBusInputContextClient* input_context_client = 393 chromeos::IBusInputContextClient* input_context_client =
447 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); 394 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
448 input_context_client->SetCommitTextHandler( 395 input_context_client->SetCommitTextHandler(
449 base::Bind(&InputMethodIBus::OnCommitText, 396 base::Bind(&InputMethodIBus::OnCommitText,
(...skipping 21 matching lines...) Expand all
471 418
472 UpdateContextFocusState(); 419 UpdateContextFocusState();
473 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or 420 // Since ibus-daemon is launched in an on-demand basis on Chrome OS, RWHVA (or
474 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To 421 // equivalents) might call OnCaretBoundsChanged() before the daemon starts. To
475 // save the case, call OnCaretBoundsChanged() here. 422 // save the case, call OnCaretBoundsChanged() here.
476 OnCaretBoundsChanged(GetTextInputClient()); 423 OnCaretBoundsChanged(GetTextInputClient());
477 OnInputMethodChanged(); 424 OnInputMethodChanged();
478 } 425 }
479 426
480 void InputMethodIBus::DestroyContext() { 427 void InputMethodIBus::DestroyContext() {
481 if (pending_create_ic_request_) { 428 if (input_context_state_ == INPUT_CONTEXT_STOP)
482 DCHECK(!IsContextReady());
483 // |pending_create_ic_request_| will be deleted in CreateInputContextDone().
484 pending_create_ic_request_->Abandon();
485 pending_create_ic_request_ = NULL;
486 return; 429 return;
487 } 430 input_context_state_ = INPUT_CONTEXT_STOP;
488 const chromeos::IBusInputContextClient* input_context = 431 const chromeos::IBusInputContextClient* input_context =
489 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); 432 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient();
490 if (input_context && input_context->IsObjectProxyReady()) { 433 if (input_context && input_context->IsObjectProxyReady()) {
491 // We can't use IsContextReady here because we want to destroy object proxy 434 // We can't use IsContextReady here because we want to destroy object proxy
492 // regardless of connection. The IsContextReady contains connection check. 435 // regardless of connection. The IsContextReady contains connection check.
493 ResetInputContext(); 436 ResetInputContext();
494 DCHECK(!IsContextReady()); 437 DCHECK(!IsContextReady());
495 } 438 }
496 } 439 }
497 440
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 context_focused_ = false; 842 context_focused_ = false;
900 843
901 ConfirmCompositionText(); 844 ConfirmCompositionText();
902 845
903 // We are dead, so we need to ask the client to stop relying on us. 846 // We are dead, so we need to ask the client to stop relying on us.
904 OnInputMethodChanged(); 847 OnInputMethodChanged();
905 GetInputContextClient()->ResetObjectProxy(); 848 GetInputContextClient()->ResetObjectProxy();
906 } 849 }
907 850
908 void InputMethodIBus::CreateInputContextDone( 851 void InputMethodIBus::CreateInputContextDone(
909 PendingCreateICRequest* ic_request,
910 const dbus::ObjectPath& object_path) { 852 const dbus::ObjectPath& object_path) {
853 DCHECK_NE(INPUT_CONTEXT_RUNNING, input_context_state_);
854
855 if (input_context_state_ == INPUT_CONTEXT_STOP) {
856 // Corresponding to cancel abandon input context under waiting
Yusuke Sato 2012/08/07 20:03:44 couldn't understand what this comment meant. pleas
Seigo Nonaka 2012/08/08 04:32:52 Sorry forget to update this comment. Done On 2012/
857 // CreateInputContext response from ibus-daemon. Do nothing.
858 return;
859 }
860
911 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient() 861 chromeos::DBusThreadManager::Get()->GetIBusInputContextClient()
912 ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(), 862 ->Initialize(chromeos::DBusThreadManager::Get()->GetIBusBus(),
913 object_path); 863 object_path);
914 ic_request->InitOrAbandonInputContext(); 864
915 delete ic_request; 865 input_context_state_ = INPUT_CONTEXT_RUNNING;
866 DCHECK(IsContextReady());
867 SetUpSignalHandlers();
916 } 868 }
917 869
918 void InputMethodIBus::CreateInputContextFail( 870 void InputMethodIBus::CreateInputContextFail() {
919 PendingCreateICRequest* ic_request) { 871 DCHECK_NE(INPUT_CONTEXT_RUNNING, input_context_state_);
920 ic_request->OnCreateInputContextFailed(); 872 if (input_context_state_ == INPUT_CONTEXT_STOP) {
921 delete ic_request; 873 // CreateInputContext failed but the input context is no longer
874 // necessary, thus do nothing.
875 return;
876 }
877
878 if (++create_input_context_fail_count_ >= kMaxRetryCount) {
879 DVLOG(1) << "CreateInputContext failed even tried "
880 << kMaxRetryCount << " times, give up.";
Yusuke Sato 2012/08/07 20:03:44 don't we need to reset the counter to zero?
Seigo Nonaka 2012/08/08 04:32:52 Yes, we need. Done. On 2012/08/07 20:03:44, Yusuke
881 return;
882 }
883
884 // Try CreateInputContext again.
885 chromeos::DBusThreadManager::Get()->GetIBusClient()->CreateInputContext(
886 kClientName,
887 base::Bind(&InputMethodIBus::CreateInputContextDone,
888 weak_ptr_factory_.GetWeakPtr()),
889 base::Bind(&InputMethodIBus::CreateInputContextFail,
890 weak_ptr_factory_.GetWeakPtr()));
922 } 891 }
923 892
924 bool InputMethodIBus::IsConnected() { 893 bool InputMethodIBus::IsConnected() {
925 return chromeos::DBusThreadManager::Get()->GetIBusBus() != NULL; 894 return chromeos::DBusThreadManager::Get()->GetIBusBus() != NULL;
926 } 895 }
927 896
928 bool InputMethodIBus::IsContextReady() { 897 bool InputMethodIBus::IsContextReady() {
929 if (!IsConnected()) 898 if (!IsConnected())
930 return false; 899 return false;
931 if (!GetInputContextClient()) 900 if (!GetInputContextClient())
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 } 995 }
1027 996
1028 // Use a black thin underline by default. 997 // Use a black thin underline by default.
1029 if (out_composition->underlines.empty()) { 998 if (out_composition->underlines.empty()) {
1030 out_composition->underlines.push_back(CompositionUnderline( 999 out_composition->underlines.push_back(CompositionUnderline(
1031 0, length, SK_ColorBLACK, false /* thick */)); 1000 0, length, SK_ColorBLACK, false /* thick */));
1032 } 1001 }
1033 } 1002 }
1034 1003
1035 } // namespace ui 1004 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698