Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/ui/input_method/input_method_engine_base.h" | 5 #include "chrome/browser/ui/input_method/input_method_engine_base.h" |
| 6 | 6 |
| 7 #undef FocusIn | 7 #undef FocusIn |
| 8 #undef FocusOut | 8 #undef FocusOut |
| 9 #undef RootWindow | 9 #undef RootWindow |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 #include "ui/events/keycodes/keyboard_codes_posix.h" | 40 #include "ui/events/keycodes/keyboard_codes_posix.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 namespace input_method { | 43 namespace input_method { |
| 44 | 44 |
| 45 namespace { | 45 namespace { |
| 46 | 46 |
| 47 const char kErrorNotActive[] = "IME is not active"; | 47 const char kErrorNotActive[] = "IME is not active"; |
| 48 const char kErrorWrongContext[] = "Context is not active"; | 48 const char kErrorWrongContext[] = "Context is not active"; |
| 49 | 49 |
| 50 // Notifies InputContextHandler that the composition is changed. | |
| 51 void UpdateComposition(const ui::CompositionText& composition_text, | |
| 52 uint32_t cursor_pos, | |
| 53 bool is_visible) { | |
| 54 ui::IMEInputContextHandlerInterface* input_context = | |
| 55 ui::IMEBridge::Get()->GetInputContextHandler(); | |
| 56 if (input_context) | |
| 57 input_context->UpdateCompositionText(composition_text, cursor_pos, | |
| 58 is_visible); | |
| 59 } | |
| 60 | |
| 61 // Returns the length of characters of a UTF-8 string with unknown string | |
| 62 // length. Cannot apply faster algorithm to count characters in an utf-8 | |
| 63 // string without knowing the string length, so just does a full scan. | |
| 64 size_t GetUtf8StringLength(const char* s) { | |
| 65 size_t ret = 0; | |
| 66 while (*s) { | |
| 67 if ((*s & 0xC0) != 0x80) | |
| 68 ret++; | |
| 69 ++s; | |
| 70 } | |
| 71 return ret; | |
| 72 } | |
| 73 | |
| 74 #if defined(OS_CHROMEOS) | 50 #if defined(OS_CHROMEOS) |
| 75 std::string GetKeyFromEvent(const ui::KeyEvent& event) { | 51 std::string GetKeyFromEvent(const ui::KeyEvent& event) { |
| 76 const std::string code = event.GetCodeString(); | 52 const std::string code = event.GetCodeString(); |
| 77 if (base::StartsWith(code, "Control", base::CompareCase::SENSITIVE)) | 53 if (base::StartsWith(code, "Control", base::CompareCase::SENSITIVE)) |
| 78 return "Ctrl"; | 54 return "Ctrl"; |
| 79 if (base::StartsWith(code, "Shift", base::CompareCase::SENSITIVE)) | 55 if (base::StartsWith(code, "Shift", base::CompareCase::SENSITIVE)) |
| 80 return "Shift"; | 56 return "Shift"; |
| 81 if (base::StartsWith(code, "Alt", base::CompareCase::SENSITIVE)) | 57 if (base::StartsWith(code, "Alt", base::CompareCase::SENSITIVE)) |
| 82 return "Alt"; | 58 return "Alt"; |
| 83 if (base::StartsWith(code, "Arrow", base::CompareCase::SENSITIVE)) | 59 if (base::StartsWith(code, "Arrow", base::CompareCase::SENSITIVE)) |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 | 149 |
| 174 InputMethodEngineBase::KeyboardEvent::~KeyboardEvent() {} | 150 InputMethodEngineBase::KeyboardEvent::~KeyboardEvent() {} |
| 175 | 151 |
| 176 InputMethodEngineBase::InputMethodEngineBase() | 152 InputMethodEngineBase::InputMethodEngineBase() |
| 177 : current_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 153 : current_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
| 178 context_id_(0), | 154 context_id_(0), |
| 179 next_context_id_(1), | 155 next_context_id_(1), |
| 180 composition_text_(new ui::CompositionText()), | 156 composition_text_(new ui::CompositionText()), |
| 181 composition_cursor_(0), | 157 composition_cursor_(0), |
| 182 sent_key_event_(NULL), | 158 sent_key_event_(NULL), |
| 183 profile_(NULL) {} | 159 profile_(NULL), |
|
Shu Chen
2016/02/04 08:00:46
s/NULL/nullptr/g
Azure Wei
2016/02/04 11:57:21
Done.
| |
| 160 text_(""), | |
| 161 handling_key_event_(false) {} | |
| 184 | 162 |
| 185 InputMethodEngineBase::~InputMethodEngineBase() {} | 163 InputMethodEngineBase::~InputMethodEngineBase() {} |
| 186 | 164 |
| 187 void InputMethodEngineBase::Initialize( | 165 void InputMethodEngineBase::Initialize( |
| 188 scoped_ptr<InputMethodEngineBase::Observer> observer, | 166 scoped_ptr<InputMethodEngineBase::Observer> observer, |
| 189 const char* extension_id, | 167 const char* extension_id, |
| 190 Profile* profile) { | 168 Profile* profile) { |
| 191 DCHECK(observer) << "Observer must not be null."; | 169 DCHECK(observer) << "Observer must not be null."; |
| 192 | 170 |
| 193 // TODO(komatsu): It is probably better to set observer out of Initialize. | 171 // TODO(komatsu): It is probably better to set observer out of Initialize. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 if (!IsActive()) { | 255 if (!IsActive()) { |
| 278 // TODO: Commit the text anyways. | 256 // TODO: Commit the text anyways. |
| 279 *error = kErrorNotActive; | 257 *error = kErrorNotActive; |
| 280 return false; | 258 return false; |
| 281 } | 259 } |
| 282 if (context_id != context_id_ || context_id_ == -1) { | 260 if (context_id != context_id_ || context_id_ == -1) { |
| 283 *error = kErrorWrongContext; | 261 *error = kErrorWrongContext; |
| 284 return false; | 262 return false; |
| 285 } | 263 } |
| 286 | 264 |
| 287 ui::IMEBridge::Get()->GetInputContextHandler()->CommitText(text); | 265 CommitTextToInputContext(context_id, std::string(text)); |
| 288 | |
| 289 // Records histograms for committed characters. | |
| 290 if (!composition_text_->text.empty()) { | |
| 291 size_t len = GetUtf8StringLength(text); | |
| 292 UMA_HISTOGRAM_CUSTOM_COUNTS("InputMethod.CommitLength", len, 1, 25, 25); | |
| 293 composition_text_.reset(new ui::CompositionText()); | |
| 294 } | |
| 295 return true; | 266 return true; |
| 296 } | 267 } |
| 297 | 268 |
| 298 bool InputMethodEngineBase::DeleteSurroundingText(int context_id, | 269 bool InputMethodEngineBase::DeleteSurroundingText(int context_id, |
| 299 int offset, | 270 int offset, |
| 300 size_t number_of_chars, | 271 size_t number_of_chars, |
| 301 std::string* error) { | 272 std::string* error) { |
| 302 if (!IsActive()) { | 273 if (!IsActive()) { |
| 303 *error = kErrorNotActive; | 274 *error = kErrorNotActive; |
| 304 return false; | 275 return false; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 composition_text_.reset(new ui::CompositionText()); | 343 composition_text_.reset(new ui::CompositionText()); |
| 373 observer_->OnReset(active_component_id_); | 344 observer_->OnReset(active_component_id_); |
| 374 } | 345 } |
| 375 | 346 |
| 376 bool InputMethodEngineBase::IsInterestedInKeyEvent() const { | 347 bool InputMethodEngineBase::IsInterestedInKeyEvent() const { |
| 377 return observer_->IsInterestedInKeyEvent(); | 348 return observer_->IsInterestedInKeyEvent(); |
| 378 } | 349 } |
| 379 | 350 |
| 380 void InputMethodEngineBase::ProcessKeyEvent(const ui::KeyEvent& key_event, | 351 void InputMethodEngineBase::ProcessKeyEvent(const ui::KeyEvent& key_event, |
| 381 KeyEventDoneCallback& callback) { | 352 KeyEventDoneCallback& callback) { |
| 353 // Make true that we don't handle IME API calling of setComposition and | |
| 354 // commitText while the extension is handling key event. | |
| 355 handling_key_event_ = true; | |
| 356 | |
| 382 KeyboardEvent ext_event; | 357 KeyboardEvent ext_event; |
| 383 GetExtensionKeyboardEventFromKeyEvent(key_event, &ext_event); | 358 GetExtensionKeyboardEventFromKeyEvent(key_event, &ext_event); |
| 384 | 359 |
| 385 // If the given key event is equal to the key event sent by | 360 // If the given key event is equal to the key event sent by |
| 386 // SendKeyEvents, this engine ID is propagated to the extension IME. | 361 // SendKeyEvents, this engine ID is propagated to the extension IME. |
| 387 // Note, this check relies on that ui::KeyEvent is propagated as | 362 // Note, this check relies on that ui::KeyEvent is propagated as |
| 388 // reference without copying. | 363 // reference without copying. |
| 389 if (&key_event == sent_key_event_) | 364 if (&key_event == sent_key_event_) |
| 390 ext_event.extension_id = extension_id_; | 365 ext_event.extension_id = extension_id_; |
| 391 | 366 |
| 392 observer_->OnKeyEvent(active_component_id_, ext_event, callback); | 367 observer_->OnKeyEvent(active_component_id_, ext_event, callback); |
| 393 } | 368 } |
| 394 | 369 |
| 395 void InputMethodEngineBase::SetSurroundingText(const std::string& text, | 370 void InputMethodEngineBase::SetSurroundingText(const std::string& text, |
| 396 uint32_t cursor_pos, | 371 uint32_t cursor_pos, |
| 397 uint32_t anchor_pos, | 372 uint32_t anchor_pos, |
| 398 uint32_t offset_pos) { | 373 uint32_t offset_pos) { |
| 399 observer_->OnSurroundingTextChanged( | 374 observer_->OnSurroundingTextChanged( |
| 400 active_component_id_, text, static_cast<int>(cursor_pos), | 375 active_component_id_, text, static_cast<int>(cursor_pos), |
| 401 static_cast<int>(anchor_pos), static_cast<int>(offset_pos)); | 376 static_cast<int>(anchor_pos), static_cast<int>(offset_pos)); |
| 402 } | 377 } |
| 403 | 378 |
| 379 void InputMethodEngineBase::KeyEventHandled() { | |
| 380 handling_key_event_ = false; | |
| 381 // When finish handling key event, take care of the unprocessed setComposition | |
| 382 // and commitText calls. | |
| 383 ui::IMEInputContextHandlerInterface* input_context = | |
| 384 ui::IMEBridge::Get()->GetInputContextHandler(); | |
| 385 if (!composition_.text.empty()) { | |
| 386 if (input_context) | |
|
Shu Chen
2016/02/04 08:00:46
bracket.
Azure Wei
2016/02/04 11:57:21
Done.
| |
| 387 input_context->UpdateCompositionText( | |
| 388 composition_, composition_.selection.start(), true); | |
| 389 composition_.Clear(); | |
| 390 } | |
| 391 if (!text_.empty()) { | |
| 392 if (input_context) | |
| 393 input_context->CommitText(text_); | |
| 394 text_ = ""; | |
| 395 } | |
| 396 } | |
| 397 | |
| 404 } // namespace input_method | 398 } // namespace input_method |
| OLD | NEW |