Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/chromeos/input_method/input_method_engine.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_engine.h" |
| 6 | 6 |
| 7 #undef FocusIn | 7 #undef FocusIn |
| 8 #undef FocusOut | 8 #undef FocusOut |
| 9 #undef RootWindow | 9 #undef RootWindow |
| 10 #include <map> | 10 #include <map> |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 ext_event->ctrl_key = event.IsControlDown(); | 105 ext_event->ctrl_key = event.IsControlDown(); |
| 106 ext_event->shift_key = event.IsShiftDown(); | 106 ext_event->shift_key = event.IsShiftDown(); |
| 107 ext_event->caps_lock = event.IsCapsLockDown(); | 107 ext_event->caps_lock = event.IsCapsLockDown(); |
| 108 ext_event->key = GetKeyFromEvent(event); | 108 ext_event->key = GetKeyFromEvent(event); |
| 109 } | 109 } |
| 110 | 110 |
| 111 } // namespace | 111 } // namespace |
| 112 | 112 |
| 113 InputMethodEngine::InputMethodEngine() | 113 InputMethodEngine::InputMethodEngine() |
| 114 : current_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 114 : current_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
| 115 active_(false), | |
| 116 context_id_(0), | 115 context_id_(0), |
| 117 next_context_id_(1), | 116 next_context_id_(1), |
| 118 composition_text_(new CompositionText()), | 117 composition_text_(new CompositionText()), |
| 119 composition_cursor_(0), | 118 composition_cursor_(0), |
| 120 candidate_window_(new ui::CandidateWindow()), | 119 candidate_window_(new ui::CandidateWindow()), |
| 121 window_visible_(false), | 120 window_visible_(false), |
| 122 sent_key_event_(NULL) {} | 121 sent_key_event_(NULL) {} |
| 123 | 122 |
| 124 InputMethodEngine::~InputMethodEngine() { | 123 InputMethodEngine::~InputMethodEngine() { |
| 125 if (start_time_.ToInternalValue()) | 124 if (start_time_.ToInternalValue()) |
| 126 RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); | 125 RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); |
| 127 input_method::InputMethodManager::Get()->RemoveInputMethodExtension(imm_id_); | |
| 128 } | 126 } |
| 129 | 127 |
| 130 void InputMethodEngine::Initialize( | 128 void InputMethodEngine::Initialize( |
| 131 scoped_ptr<InputMethodEngineInterface::Observer> observer, | 129 scoped_ptr<InputMethodEngineInterface::Observer> observer, |
| 132 const char* engine_name, | 130 const char* extension_id) { |
| 133 const char* extension_id, | |
| 134 const char* engine_id, | |
| 135 const std::vector<std::string>& languages, | |
| 136 const std::vector<std::string>& layouts, | |
| 137 const GURL& options_page, | |
| 138 const GURL& input_view) { | |
| 139 DCHECK(observer) << "Observer must not be null."; | 131 DCHECK(observer) << "Observer must not be null."; |
| 140 | 132 |
| 141 // TODO(komatsu): It is probably better to set observer out of Initialize. | 133 // TODO(komatsu): It is probably better to set observer out of Initialize. |
| 142 observer_ = observer.Pass(); | 134 observer_ = observer.Pass(); |
| 143 engine_id_ = engine_id; | |
| 144 extension_id_ = extension_id; | 135 extension_id_ = extension_id; |
| 145 | |
| 146 input_method::InputMethodManager* manager = | |
| 147 input_method::InputMethodManager::Get(); | |
| 148 ComponentExtensionIMEManager* comp_ext_ime_manager = | |
| 149 manager->GetComponentExtensionIMEManager(); | |
| 150 | |
| 151 if (comp_ext_ime_manager->IsWhitelistedExtension(extension_id)) { | |
| 152 imm_id_ = comp_ext_ime_manager->GetId(extension_id, engine_id); | |
| 153 } else { | |
| 154 imm_id_ = extension_ime_util::GetInputMethodID(extension_id, engine_id); | |
| 155 } | |
| 156 | |
| 157 input_view_url_ = input_view; | |
| 158 descriptor_ = input_method::InputMethodDescriptor( | |
| 159 imm_id_, | |
| 160 engine_name, | |
| 161 std::string(), // TODO(uekawa): Set short name. | |
| 162 layouts, | |
| 163 languages, | |
| 164 extension_ime_util::IsKeyboardLayoutExtension( | |
| 165 imm_id_), // is_login_keyboard | |
| 166 options_page, | |
| 167 input_view); | |
| 168 | |
| 169 // TODO(komatsu): It is probably better to call AddInputMethodExtension | |
| 170 // out of Initialize. | |
| 171 manager->AddInputMethodExtension(imm_id_, this); | |
| 172 } | |
| 173 | |
| 174 const input_method::InputMethodDescriptor& InputMethodEngine::GetDescriptor() | |
| 175 const { | |
| 176 return descriptor_; | |
| 177 } | 136 } |
| 178 | 137 |
| 179 void InputMethodEngine::RecordHistogram(const char* name, int count) { | 138 void InputMethodEngine::RecordHistogram(const char* name, int count) { |
| 180 std::string histo_name = | 139 std::string histo_name = |
| 181 base::StringPrintf("InputMethod.%s.%s", name, engine_id_.c_str()); | 140 base::StringPrintf("InputMethod.%s.%s", name, active_engine_id_.c_str()); |
| 182 base::HistogramBase* counter = base::Histogram::FactoryGet( | 141 base::HistogramBase* counter = base::Histogram::FactoryGet( |
| 183 histo_name, 0, 1000000, 50, base::HistogramBase::kNoFlags); | 142 histo_name, 0, 1000000, 50, base::HistogramBase::kNoFlags); |
| 184 if (counter) | 143 if (counter) |
| 185 counter->Add(count); | 144 counter->Add(count); |
| 186 } | 145 } |
| 187 | 146 |
| 188 void InputMethodEngine::NotifyImeReady() { | 147 const std::string& InputMethodEngine::GetActiveEngineId() const { |
| 189 input_method::InputMethodManager* manager = | 148 return active_engine_id_; |
| 190 input_method::InputMethodManager::Get(); | |
| 191 if (manager && imm_id_ == manager->GetCurrentInputMethod().id()) | |
| 192 Enable(); | |
| 193 } | 149 } |
| 194 | 150 |
| 195 bool InputMethodEngine::SetComposition( | 151 bool InputMethodEngine::SetComposition( |
| 196 int context_id, | 152 int context_id, |
| 197 const char* text, | 153 const char* text, |
| 198 int selection_start, | 154 int selection_start, |
| 199 int selection_end, | 155 int selection_end, |
| 200 int cursor, | 156 int cursor, |
| 201 const std::vector<SegmentInfo>& segments, | 157 const std::vector<SegmentInfo>& segments, |
| 202 std::string* error) { | 158 std::string* error) { |
| 203 if (!active_) { | 159 if (!IsActive()) { |
| 204 *error = kErrorNotActive; | 160 *error = kErrorNotActive; |
| 205 return false; | 161 return false; |
| 206 } | 162 } |
| 207 if (context_id != context_id_ || context_id_ == -1) { | 163 if (context_id != context_id_ || context_id_ == -1) { |
| 208 *error = kErrorWrongContext; | 164 *error = kErrorWrongContext; |
| 209 return false; | 165 return false; |
| 210 } | 166 } |
| 211 | 167 |
| 212 composition_cursor_ = cursor; | 168 composition_cursor_ = cursor; |
| 213 composition_text_.reset(new CompositionText()); | 169 composition_text_.reset(new CompositionText()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 237 composition_text_->mutable_underline_attributes()->push_back(underline); | 193 composition_text_->mutable_underline_attributes()->push_back(underline); |
| 238 } | 194 } |
| 239 | 195 |
| 240 // TODO(nona): Makes focus out mode configuable, if necessary. | 196 // TODO(nona): Makes focus out mode configuable, if necessary. |
| 241 UpdateComposition(*composition_text_, composition_cursor_, true); | 197 UpdateComposition(*composition_text_, composition_cursor_, true); |
| 242 return true; | 198 return true; |
| 243 } | 199 } |
| 244 | 200 |
| 245 bool InputMethodEngine::ClearComposition(int context_id, | 201 bool InputMethodEngine::ClearComposition(int context_id, |
| 246 std::string* error) { | 202 std::string* error) { |
| 247 if (!active_) { | 203 if (!IsActive()) { |
| 248 *error = kErrorNotActive; | 204 *error = kErrorNotActive; |
| 249 return false; | 205 return false; |
| 250 } | 206 } |
| 251 if (context_id != context_id_ || context_id_ == -1) { | 207 if (context_id != context_id_ || context_id_ == -1) { |
| 252 *error = kErrorWrongContext; | 208 *error = kErrorWrongContext; |
| 253 return false; | 209 return false; |
| 254 } | 210 } |
| 255 | 211 |
| 256 composition_cursor_ = 0; | 212 composition_cursor_ = 0; |
| 257 composition_text_.reset(new CompositionText()); | 213 composition_text_.reset(new CompositionText()); |
| 258 UpdateComposition(*composition_text_, composition_cursor_, false); | 214 UpdateComposition(*composition_text_, composition_cursor_, false); |
| 259 return true; | 215 return true; |
| 260 } | 216 } |
| 261 | 217 |
| 262 bool InputMethodEngine::CommitText(int context_id, const char* text, | 218 bool InputMethodEngine::CommitText(int context_id, const char* text, |
| 263 std::string* error) { | 219 std::string* error) { |
| 264 if (!active_) { | 220 if (!IsActive()) { |
| 265 // TODO: Commit the text anyways. | 221 // TODO: Commit the text anyways. |
| 266 *error = kErrorNotActive; | 222 *error = kErrorNotActive; |
| 267 return false; | 223 return false; |
| 268 } | 224 } |
| 269 if (context_id != context_id_ || context_id_ == -1) { | 225 if (context_id != context_id_ || context_id_ == -1) { |
| 270 *error = kErrorWrongContext; | 226 *error = kErrorWrongContext; |
| 271 return false; | 227 return false; |
| 272 } | 228 } |
| 273 | 229 |
| 274 IMEBridge::Get()->GetInputContextHandler()->CommitText(text); | 230 IMEBridge::Get()->GetInputContextHandler()->CommitText(text); |
| 275 | 231 |
| 276 // Records times for using input method. | 232 // Records times for using input method. |
| 277 if (!start_time_.ToInternalValue()) | 233 if (!start_time_.ToInternalValue()) |
| 278 start_time_ = base::Time::Now(); | 234 start_time_ = base::Time::Now(); |
| 279 end_time_ = base::Time::Now(); | 235 end_time_ = base::Time::Now(); |
| 280 // Records histograms for counts of commits and committed characters. | 236 // Records histograms for counts of commits and committed characters. |
| 281 RecordHistogram("Commit", 1); | 237 RecordHistogram("Commit", 1); |
| 282 RecordHistogram("CommitCharacter", GetUtf8StringLength(text)); | 238 RecordHistogram("CommitCharacter", GetUtf8StringLength(text)); |
| 283 return true; | 239 return true; |
| 284 } | 240 } |
| 285 | 241 |
| 286 bool InputMethodEngine::SendKeyEvents( | 242 bool InputMethodEngine::SendKeyEvents( |
| 287 int context_id, | 243 int context_id, |
| 288 const std::vector<KeyboardEvent>& events) { | 244 const std::vector<KeyboardEvent>& events) { |
| 289 if (!active_) { | 245 if (!IsActive()) { |
| 290 return false; | 246 return false; |
| 291 } | 247 } |
| 292 // context_id == 0, means sending key events to non-input field. | 248 // context_id == 0, means sending key events to non-input field. |
| 293 // context_id_ == -1, means the focus is not in an input field. | 249 // context_id_ == -1, means the focus is not in an input field. |
| 294 if (context_id != 0 && (context_id != context_id_ || context_id_ == -1)) { | 250 if (context_id != 0 && (context_id != context_id_ || context_id_ == -1)) { |
| 295 return false; | 251 return false; |
| 296 } | 252 } |
| 297 | 253 |
| 298 ui::EventProcessor* dispatcher = | 254 ui::EventProcessor* dispatcher = |
| 299 ash::Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); | 255 ash::Shell::GetPrimaryRootWindow()->GetHost()->event_processor(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 dest_property.show_window_at_composition = | 304 dest_property.show_window_at_composition = |
| 349 property.show_window_at_composition; | 305 property.show_window_at_composition; |
| 350 dest_property.cursor_position = | 306 dest_property.cursor_position = |
| 351 candidate_window_->GetProperty().cursor_position; | 307 candidate_window_->GetProperty().cursor_position; |
| 352 dest_property.auxiliary_text = property.auxiliary_text; | 308 dest_property.auxiliary_text = property.auxiliary_text; |
| 353 dest_property.is_auxiliary_text_visible = property.is_auxiliary_text_visible; | 309 dest_property.is_auxiliary_text_visible = property.is_auxiliary_text_visible; |
| 354 | 310 |
| 355 candidate_window_->SetProperty(dest_property); | 311 candidate_window_->SetProperty(dest_property); |
| 356 candidate_window_property_ = property; | 312 candidate_window_property_ = property; |
| 357 | 313 |
| 358 if (active_) { | 314 if (IsActive()) { |
| 359 IMECandidateWindowHandlerInterface* cw_handler = | 315 IMECandidateWindowHandlerInterface* cw_handler = |
| 360 IMEBridge::Get()->GetCandidateWindowHandler(); | 316 IMEBridge::Get()->GetCandidateWindowHandler(); |
| 361 if (cw_handler) | 317 if (cw_handler) |
| 362 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 318 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
| 363 } | 319 } |
| 364 } | 320 } |
| 365 | 321 |
| 366 bool InputMethodEngine::SetCandidateWindowVisible(bool visible, | 322 bool InputMethodEngine::SetCandidateWindowVisible(bool visible, |
| 367 std::string* error) { | 323 std::string* error) { |
| 368 if (!active_) { | 324 if (!IsActive()) { |
| 369 *error = kErrorNotActive; | 325 *error = kErrorNotActive; |
| 370 return false; | 326 return false; |
| 371 } | 327 } |
| 372 | 328 |
| 373 window_visible_ = visible; | 329 window_visible_ = visible; |
| 374 IMECandidateWindowHandlerInterface* cw_handler = | 330 IMECandidateWindowHandlerInterface* cw_handler = |
| 375 IMEBridge::Get()->GetCandidateWindowHandler(); | 331 IMEBridge::Get()->GetCandidateWindowHandler(); |
| 376 if (cw_handler) | 332 if (cw_handler) |
| 377 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 333 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
| 378 return true; | 334 return true; |
| 379 } | 335 } |
| 380 | 336 |
| 381 bool InputMethodEngine::SetCandidates( | 337 bool InputMethodEngine::SetCandidates( |
| 382 int context_id, | 338 int context_id, |
| 383 const std::vector<Candidate>& candidates, | 339 const std::vector<Candidate>& candidates, |
| 384 std::string* error) { | 340 std::string* error) { |
| 385 if (!active_) { | 341 if (!IsActive()) { |
| 386 *error = kErrorNotActive; | 342 *error = kErrorNotActive; |
| 387 return false; | 343 return false; |
| 388 } | 344 } |
| 389 if (context_id != context_id_ || context_id_ == -1) { | 345 if (context_id != context_id_ || context_id_ == -1) { |
| 390 *error = kErrorWrongContext; | 346 *error = kErrorWrongContext; |
| 391 return false; | 347 return false; |
| 392 } | 348 } |
| 393 | 349 |
| 394 // TODO: Nested candidates | 350 // TODO: Nested candidates |
| 395 candidate_ids_.clear(); | 351 candidate_ids_.clear(); |
| 396 candidate_indexes_.clear(); | 352 candidate_indexes_.clear(); |
| 397 candidate_window_->mutable_candidates()->clear(); | 353 candidate_window_->mutable_candidates()->clear(); |
| 398 for (std::vector<Candidate>::const_iterator ix = candidates.begin(); | 354 for (std::vector<Candidate>::const_iterator ix = candidates.begin(); |
| 399 ix != candidates.end(); ++ix) { | 355 ix != candidates.end(); ++ix) { |
| 400 ui::CandidateWindow::Entry entry; | 356 ui::CandidateWindow::Entry entry; |
| 401 entry.value = base::UTF8ToUTF16(ix->value); | 357 entry.value = base::UTF8ToUTF16(ix->value); |
| 402 entry.label = base::UTF8ToUTF16(ix->label); | 358 entry.label = base::UTF8ToUTF16(ix->label); |
| 403 entry.annotation = base::UTF8ToUTF16(ix->annotation); | 359 entry.annotation = base::UTF8ToUTF16(ix->annotation); |
| 404 entry.description_title = base::UTF8ToUTF16(ix->usage.title); | 360 entry.description_title = base::UTF8ToUTF16(ix->usage.title); |
| 405 entry.description_body = base::UTF8ToUTF16(ix->usage.body); | 361 entry.description_body = base::UTF8ToUTF16(ix->usage.body); |
| 406 | 362 |
| 407 // Store a mapping from the user defined ID to the candidate index. | 363 // Store a mapping from the user defined ID to the candidate index. |
| 408 candidate_indexes_[ix->id] = candidate_ids_.size(); | 364 candidate_indexes_[ix->id] = candidate_ids_.size(); |
| 409 candidate_ids_.push_back(ix->id); | 365 candidate_ids_.push_back(ix->id); |
| 410 | 366 |
| 411 candidate_window_->mutable_candidates()->push_back(entry); | 367 candidate_window_->mutable_candidates()->push_back(entry); |
| 412 } | 368 } |
| 413 if (active_) { | 369 if (IsActive()) { |
| 414 IMECandidateWindowHandlerInterface* cw_handler = | 370 IMECandidateWindowHandlerInterface* cw_handler = |
| 415 IMEBridge::Get()->GetCandidateWindowHandler(); | 371 IMEBridge::Get()->GetCandidateWindowHandler(); |
| 416 if (cw_handler) | 372 if (cw_handler) |
| 417 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 373 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
| 418 } | 374 } |
| 419 return true; | 375 return true; |
| 420 } | 376 } |
| 421 | 377 |
| 422 bool InputMethodEngine::SetCursorPosition(int context_id, int candidate_id, | 378 bool InputMethodEngine::SetCursorPosition(int context_id, int candidate_id, |
| 423 std::string* error) { | 379 std::string* error) { |
| 424 if (!active_) { | 380 if (!IsActive()) { |
| 425 *error = kErrorNotActive; | 381 *error = kErrorNotActive; |
| 426 return false; | 382 return false; |
| 427 } | 383 } |
| 428 if (context_id != context_id_ || context_id_ == -1) { | 384 if (context_id != context_id_ || context_id_ == -1) { |
| 429 *error = kErrorWrongContext; | 385 *error = kErrorWrongContext; |
| 430 return false; | 386 return false; |
| 431 } | 387 } |
| 432 | 388 |
| 433 std::map<int, int>::const_iterator position = | 389 std::map<int, int>::const_iterator position = |
| 434 candidate_indexes_.find(candidate_id); | 390 candidate_indexes_.find(candidate_id); |
| 435 if (position == candidate_indexes_.end()) { | 391 if (position == candidate_indexes_.end()) { |
| 436 *error = kCandidateNotFound; | 392 *error = kCandidateNotFound; |
| 437 return false; | 393 return false; |
| 438 } | 394 } |
| 439 | 395 |
| 440 candidate_window_->set_cursor_position(position->second); | 396 candidate_window_->set_cursor_position(position->second); |
| 441 IMECandidateWindowHandlerInterface* cw_handler = | 397 IMECandidateWindowHandlerInterface* cw_handler = |
| 442 IMEBridge::Get()->GetCandidateWindowHandler(); | 398 IMEBridge::Get()->GetCandidateWindowHandler(); |
| 443 if (cw_handler) | 399 if (cw_handler) |
| 444 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 400 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
| 445 return true; | 401 return true; |
| 446 } | 402 } |
| 447 | 403 |
| 448 bool InputMethodEngine::SetMenuItems(const std::vector<MenuItem>& items) { | 404 bool InputMethodEngine::SetMenuItems(const std::vector<MenuItem>& items) { |
| 449 return UpdateMenuItems(items); | 405 return UpdateMenuItems(items); |
| 450 } | 406 } |
| 451 | 407 |
| 452 bool InputMethodEngine::UpdateMenuItems( | 408 bool InputMethodEngine::UpdateMenuItems( |
| 453 const std::vector<MenuItem>& items) { | 409 const std::vector<MenuItem>& items) { |
| 454 if (!active_) | 410 if (!IsActive()) |
| 455 return false; | 411 return false; |
| 456 | 412 |
| 457 ash::ime::InputMethodMenuItemList menu_item_list; | 413 ash::ime::InputMethodMenuItemList menu_item_list; |
| 458 for (std::vector<MenuItem>::const_iterator item = items.begin(); | 414 for (std::vector<MenuItem>::const_iterator item = items.begin(); |
| 459 item != items.end(); ++item) { | 415 item != items.end(); ++item) { |
| 460 ash::ime::InputMethodMenuItem property; | 416 ash::ime::InputMethodMenuItem property; |
| 461 MenuItemToProperty(*item, &property); | 417 MenuItemToProperty(*item, &property); |
| 462 menu_item_list.push_back(property); | 418 menu_item_list.push_back(property); |
| 463 } | 419 } |
| 464 | 420 |
| 465 ash::ime::InputMethodMenuManager::GetInstance()-> | 421 ash::ime::InputMethodMenuManager::GetInstance()-> |
| 466 SetCurrentInputMethodMenuItemList( | 422 SetCurrentInputMethodMenuItemList( |
| 467 menu_item_list); | 423 menu_item_list); |
| 468 return true; | 424 return true; |
| 469 } | 425 } |
| 470 | 426 |
| 471 bool InputMethodEngine::IsActive() const { | 427 bool InputMethodEngine::IsActive() const { |
| 472 return active_; | 428 return !active_engine_id_.empty(); |
| 473 } | 429 } |
| 474 | 430 |
| 475 bool InputMethodEngine::DeleteSurroundingText(int context_id, | 431 bool InputMethodEngine::DeleteSurroundingText(int context_id, |
| 476 int offset, | 432 int offset, |
| 477 size_t number_of_chars, | 433 size_t number_of_chars, |
| 478 std::string* error) { | 434 std::string* error) { |
| 479 if (!active_) { | 435 if (!IsActive()) { |
| 480 *error = kErrorNotActive; | 436 *error = kErrorNotActive; |
| 481 return false; | 437 return false; |
| 482 } | 438 } |
| 483 if (context_id != context_id_ || context_id_ == -1) { | 439 if (context_id != context_id_ || context_id_ == -1) { |
| 484 *error = kErrorWrongContext; | 440 *error = kErrorWrongContext; |
| 485 return false; | 441 return false; |
| 486 } | 442 } |
| 487 | 443 |
| 488 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) | 444 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) |
| 489 return false; // Currently we can only support preceding text. | 445 return false; // Currently we can only support preceding text. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 501 void InputMethodEngine::HideInputView() { | 457 void InputMethodEngine::HideInputView() { |
| 502 keyboard::KeyboardController* keyboard_controller = | 458 keyboard::KeyboardController* keyboard_controller = |
| 503 keyboard::KeyboardController::GetInstance(); | 459 keyboard::KeyboardController::GetInstance(); |
| 504 if (keyboard_controller) { | 460 if (keyboard_controller) { |
| 505 keyboard_controller->HideKeyboard( | 461 keyboard_controller->HideKeyboard( |
| 506 keyboard::KeyboardController::HIDE_REASON_MANUAL); | 462 keyboard::KeyboardController::HIDE_REASON_MANUAL); |
| 507 } | 463 } |
| 508 } | 464 } |
| 509 | 465 |
| 510 void InputMethodEngine::EnableInputView(bool enabled) { | 466 void InputMethodEngine::EnableInputView(bool enabled) { |
| 511 const GURL& url = enabled ? input_view_url_ : GURL(); | 467 const GURL& url = enabled && GetCurrentInputMethod() ? |
| 468 GetCurrentInputMethod()->input_view_url() : GURL(); | |
| 512 keyboard::SetOverrideContentUrl(url); | 469 keyboard::SetOverrideContentUrl(url); |
| 513 keyboard::KeyboardController* keyboard_controller = | 470 keyboard::KeyboardController* keyboard_controller = |
| 514 keyboard::KeyboardController::GetInstance(); | 471 keyboard::KeyboardController::GetInstance(); |
| 515 if (keyboard_controller) | 472 if (keyboard_controller) |
| 516 keyboard_controller->Reload(); | 473 keyboard_controller->Reload(); |
| 517 } | 474 } |
| 518 | 475 |
| 476 const input_method::InputMethodDescriptor* | |
| 477 InputMethodEngine::GetCurrentInputMethod() { | |
| 478 input_method::InputMethodManager* manager = | |
| 479 input_method::InputMethodManager::Get(); | |
|
Shu Chen
2014/08/04 15:59:31
Here could just use input_method::InputMethodManag
Seigo Nonaka
2014/08/04 23:29:47
Seems yes.
On 2014/08/04 15:59:31, Shu Chen wrote
Shu Chen
2014/08/05 01:23:09
Done.
Shu Chen
2014/08/05 01:59:03
Changed and found a bug. Enable() method is called
| |
| 480 ComponentExtensionIMEManager* comp_manager = | |
| 481 manager->GetComponentExtensionIMEManager(); | |
| 482 std::string input_method_id; | |
| 483 if (comp_manager->IsWhitelistedExtension(extension_id_)) | |
| 484 input_method_id = extension_ime_util::GetComponentInputMethodID( | |
| 485 extension_id_, active_engine_id_); | |
| 486 else | |
| 487 input_method_id = extension_ime_util::GetInputMethodID( | |
| 488 extension_id_, active_engine_id_); | |
| 489 return manager->GetInputMethodFromId(input_method_id); | |
| 490 } | |
| 491 | |
| 519 void InputMethodEngine::FocusIn( | 492 void InputMethodEngine::FocusIn( |
| 520 const IMEEngineHandlerInterface::InputContext& input_context) { | 493 const IMEEngineHandlerInterface::InputContext& input_context) { |
| 521 current_input_type_ = input_context.type; | 494 current_input_type_ = input_context.type; |
| 522 | 495 |
| 523 if (!active_ || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE) | 496 if (!IsActive() || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE) |
| 524 return; | 497 return; |
| 525 | 498 |
| 526 context_id_ = next_context_id_; | 499 context_id_ = next_context_id_; |
| 527 ++next_context_id_; | 500 ++next_context_id_; |
| 528 | 501 |
| 529 InputMethodEngineInterface::InputContext context; | 502 InputMethodEngineInterface::InputContext context; |
| 530 context.id = context_id_; | 503 context.id = context_id_; |
| 531 switch (current_input_type_) { | 504 switch (current_input_type_) { |
| 532 case ui::TEXT_INPUT_TYPE_SEARCH: | 505 case ui::TEXT_INPUT_TYPE_SEARCH: |
| 533 context.type = "search"; | 506 context.type = "search"; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 549 break; | 522 break; |
| 550 default: | 523 default: |
| 551 context.type = "text"; | 524 context.type = "text"; |
| 552 break; | 525 break; |
| 553 } | 526 } |
| 554 | 527 |
| 555 observer_->OnFocus(context); | 528 observer_->OnFocus(context); |
| 556 } | 529 } |
| 557 | 530 |
| 558 void InputMethodEngine::FocusOut() { | 531 void InputMethodEngine::FocusOut() { |
| 559 if (!active_ || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE) | 532 if (!IsActive() || current_input_type_ == ui::TEXT_INPUT_TYPE_NONE) |
| 560 return; | 533 return; |
| 561 | 534 |
| 562 current_input_type_ = ui::TEXT_INPUT_TYPE_NONE; | 535 current_input_type_ = ui::TEXT_INPUT_TYPE_NONE; |
| 563 | 536 |
| 564 int context_id = context_id_; | 537 int context_id = context_id_; |
| 565 context_id_ = -1; | 538 context_id_ = -1; |
| 566 observer_->OnBlur(context_id); | 539 observer_->OnBlur(context_id); |
| 567 } | 540 } |
| 568 | 541 |
| 569 void InputMethodEngine::Enable() { | 542 void InputMethodEngine::Enable(const std::string& engine_id) { |
| 570 active_ = true; | 543 DCHECK(!engine_id.empty()); |
| 571 observer_->OnActivate(engine_id_); | 544 active_engine_id_ = engine_id; |
| 545 observer_->OnActivate(engine_id); | |
| 572 current_input_type_ = IMEBridge::Get()->GetCurrentTextInputType(); | 546 current_input_type_ = IMEBridge::Get()->GetCurrentTextInputType(); |
| 573 FocusIn(IMEEngineHandlerInterface::InputContext( | 547 FocusIn(IMEEngineHandlerInterface::InputContext( |
| 574 current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT)); | 548 current_input_type_, ui::TEXT_INPUT_MODE_DEFAULT)); |
| 575 EnableInputView(true); | 549 EnableInputView(true); |
| 576 | 550 |
| 577 start_time_ = base::Time(); | 551 start_time_ = base::Time(); |
| 578 end_time_ = base::Time(); | 552 end_time_ = base::Time(); |
| 579 RecordHistogram("Enable", 1); | 553 RecordHistogram("Enable", 1); |
| 580 } | 554 } |
| 581 | 555 |
| 582 void InputMethodEngine::Disable() { | 556 void InputMethodEngine::Disable() { |
| 583 active_ = false; | 557 active_engine_id_ = ""; |
| 584 observer_->OnDeactivated(engine_id_); | 558 observer_->OnDeactivated(active_engine_id_); |
| 585 | 559 |
| 586 if (start_time_.ToInternalValue()) | 560 if (start_time_.ToInternalValue()) |
| 587 RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); | 561 RecordHistogram("WorkingTime", (end_time_ - start_time_).InSeconds()); |
| 588 } | 562 } |
| 589 | 563 |
| 590 void InputMethodEngine::PropertyActivate(const std::string& property_name) { | 564 void InputMethodEngine::PropertyActivate(const std::string& property_name) { |
| 591 observer_->OnMenuItemActivated(engine_id_, property_name); | 565 observer_->OnMenuItemActivated(active_engine_id_, property_name); |
| 592 } | 566 } |
| 593 | 567 |
| 594 void InputMethodEngine::Reset() { | 568 void InputMethodEngine::Reset() { |
| 595 observer_->OnReset(engine_id_); | 569 observer_->OnReset(active_engine_id_); |
| 596 } | 570 } |
| 597 | 571 |
| 598 void InputMethodEngine::ProcessKeyEvent( | 572 void InputMethodEngine::ProcessKeyEvent( |
| 599 const ui::KeyEvent& key_event, | 573 const ui::KeyEvent& key_event, |
| 600 const KeyEventDoneCallback& callback) { | 574 const KeyEventDoneCallback& callback) { |
| 601 | 575 |
| 602 KeyEventDoneCallback *handler = new KeyEventDoneCallback(); | 576 KeyEventDoneCallback *handler = new KeyEventDoneCallback(); |
| 603 *handler = callback; | 577 *handler = callback; |
| 604 | 578 |
| 605 KeyboardEvent ext_event; | 579 KeyboardEvent ext_event; |
| 606 GetExtensionKeyboardEventFromKeyEvent(key_event, &ext_event); | 580 GetExtensionKeyboardEventFromKeyEvent(key_event, &ext_event); |
| 607 | 581 |
| 608 // If the given key event is equal to the key event sent by | 582 // If the given key event is equal to the key event sent by |
| 609 // SendKeyEvents, this engine ID is propagated to the extension IME. | 583 // SendKeyEvents, this engine ID is propagated to the extension IME. |
| 610 // Note, this check relies on that ui::KeyEvent is propagated as | 584 // Note, this check relies on that ui::KeyEvent is propagated as |
| 611 // reference without copying. | 585 // reference without copying. |
| 612 if (&key_event == sent_key_event_) | 586 if (&key_event == sent_key_event_) |
| 613 ext_event.extension_id = extension_id_; | 587 ext_event.extension_id = extension_id_; |
| 614 | 588 |
| 615 observer_->OnKeyEvent( | 589 observer_->OnKeyEvent( |
| 616 engine_id_, | 590 active_engine_id_, |
| 617 ext_event, | 591 ext_event, |
| 618 reinterpret_cast<input_method::KeyEventHandle*>(handler)); | 592 reinterpret_cast<input_method::KeyEventHandle*>(handler)); |
| 619 } | 593 } |
| 620 | 594 |
| 621 void InputMethodEngine::CandidateClicked(uint32 index) { | 595 void InputMethodEngine::CandidateClicked(uint32 index) { |
| 622 if (index > candidate_ids_.size()) { | 596 if (index > candidate_ids_.size()) { |
| 623 return; | 597 return; |
| 624 } | 598 } |
| 625 | 599 |
| 626 // Only left button click is supported at this moment. | 600 // Only left button click is supported at this moment. |
| 627 observer_->OnCandidateClicked( | 601 observer_->OnCandidateClicked( |
| 628 engine_id_, candidate_ids_.at(index), MOUSE_BUTTON_LEFT); | 602 active_engine_id_, candidate_ids_.at(index), MOUSE_BUTTON_LEFT); |
| 629 } | 603 } |
| 630 | 604 |
| 631 void InputMethodEngine::SetSurroundingText(const std::string& text, | 605 void InputMethodEngine::SetSurroundingText(const std::string& text, |
| 632 uint32 cursor_pos, | 606 uint32 cursor_pos, |
| 633 uint32 anchor_pos) { | 607 uint32 anchor_pos) { |
| 634 observer_->OnSurroundingTextChanged(engine_id_, | 608 observer_->OnSurroundingTextChanged(active_engine_id_, |
| 635 text, | 609 text, |
| 636 static_cast<int>(cursor_pos), | 610 static_cast<int>(cursor_pos), |
| 637 static_cast<int>(anchor_pos)); | 611 static_cast<int>(anchor_pos)); |
| 638 } | 612 } |
| 639 | 613 |
| 640 // TODO(uekawa): rename this method to a more reasonable name. | 614 // TODO(uekawa): rename this method to a more reasonable name. |
| 641 void InputMethodEngine::MenuItemToProperty( | 615 void InputMethodEngine::MenuItemToProperty( |
| 642 const MenuItem& item, | 616 const MenuItem& item, |
| 643 ash::ime::InputMethodMenuItem* property) { | 617 ash::ime::InputMethodMenuItem* property) { |
| 644 property->key = item.id; | 618 property->key = item.id; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 673 // TODO(nona): Implement it. | 647 // TODO(nona): Implement it. |
| 674 break; | 648 break; |
| 675 } | 649 } |
| 676 } | 650 } |
| 677 } | 651 } |
| 678 | 652 |
| 679 // TODO(nona): Support item.children. | 653 // TODO(nona): Support item.children. |
| 680 } | 654 } |
| 681 | 655 |
| 682 } // namespace chromeos | 656 } // namespace chromeos |
| OLD | NEW |