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 |