diff options
-rw-r--r-- | chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc | 30 | ||||
-rw-r--r-- | chrome/common/extensions/api/input_ime.json | 14 | ||||
-rw-r--r-- | extensions/browser/extension_event_histogram_value.h | 1 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 1 | ||||
-rw-r--r-- | ui/base/ime/input_method_auralinux.cc | 4 | ||||
-rw-r--r-- | ui/base/ime/input_method_base.cc | 17 | ||||
-rw-r--r-- | ui/base/ime/input_method_base.h | 5 | ||||
-rw-r--r-- | ui/base/ime/input_method_chromeos.cc | 31 | ||||
-rw-r--r-- | ui/base/ime/input_method_win.cc | 4 |
9 files changed, 87 insertions, 20 deletions
diff --git a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc index 164a895..0499e62 100644 --- a/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc +++ b/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc @@ -12,10 +12,16 @@ #include "base/command_line.h" #include "base/macros.h" +#include "base/memory/linked_ptr.h" #include "chrome/browser/ui/input_method/input_method_engine.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/api/input_ime.h" #include "ui/base/ime/ime_bridge.h" +#include "ui/gfx/geometry/rect.h" +namespace input_ime = extensions::api::input_ime; +namespace OnCompositionBoundsChanged = + extensions::api::input_ime::OnCompositionBoundsChanged; using ui::IMEEngineHandlerInterface; using input_method::InputMethodEngine; using input_method::InputMethodEngineBase; @@ -38,6 +44,30 @@ class ImeObserverNonChromeOS : public ui::ImeObserver { ~ImeObserverNonChromeOS() override {} + void OnCompositionBoundsChanged( + const std::vector<gfx::Rect>& bounds) override { + if (extension_id_.empty() || bounds.empty() || + !HasListener(OnCompositionBoundsChanged::kEventName)) + return; + + std::vector<linked_ptr<input_ime::Bounds>> bounds_list; + for (const auto& bound : bounds) { + linked_ptr<input_ime::Bounds> bounds_value(new input_ime::Bounds()); + bounds_value->left = bound.x(); + bounds_value->top = bound.y(); + bounds_value->width = bound.width(); + bounds_value->height = bound.height(); + bounds_list.push_back(bounds_value); + } + + scoped_ptr<base::ListValue> args( + OnCompositionBoundsChanged::Create(bounds_list)); + + DispatchEventToExtension( + extensions::events::INPUT_IME_ON_COMPOSITION_BOUNDS_CHANGED, + OnCompositionBoundsChanged::kEventName, std::move(args)); + } + private: // ImeObserver overrides. void DispatchEventToExtension( diff --git a/chrome/common/extensions/api/input_ime.json b/chrome/common/extensions/api/input_ime.json index a4a2db7..1d5cb68 100644 --- a/chrome/common/extensions/api/input_ime.json +++ b/chrome/common/extensions/api/input_ime.json @@ -830,6 +830,20 @@ "description": "ID of the engine receiving the event" } ] + }, + { + "name": "onCompositionBoundsChanged", + "type": "function", + "description": "Triggered when the bounds of the IME composition text or cursor are changed. The IME composition text is the instance of text produced in the input method editor.", + "platforms": ["win", "linux"], + "parameters": [ + { + "type": "array", + "name": "boundsList", + "description": "List of bounds information for each character on IME composition text. If there's no composition text in the editor, this array contains the bound information of the cursor.", + "items": { "$ref": "Bounds" } + } + ] } ] } diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h index 6d0b30e..b77aa89 100644 --- a/extensions/browser/extension_event_histogram_value.h +++ b/extensions/browser/extension_event_histogram_value.h @@ -411,6 +411,7 @@ enum HistogramValue { EASY_UNLOCK_PRIVATE_ON_DATA_RECEIVED, EASY_UNLOCK_PRIVATE_ON_SEND_COMPLETED, DISPLAY_SOURCE_ON_SINKS_UPDATED, + INPUT_IME_ON_COMPOSITION_BOUNDS_CHANGED, // Last entry: Add new entries above, then run: // python tools/metrics/histograms/update_extension_histograms.py ENUM_BOUNDARY diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 2422a81..d48bf55 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -63109,6 +63109,7 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. <int value="390" label="EASY_UNLOCK_PRIVATE_ON_DATA_RECEIVED"/> <int value="391" label="EASY_UNLOCK_PRIVATE_ON_SEND_COMPLETED"/> <int value="392" label="DISPLAY_SOURCE_ON_SINKS_UPDATED"/> + <int value="393" label="INPUT_IME_ON_COMPOSITION_BOUNDS_CHANGED"/> </enum> <enum name="ExtensionFileWriteResult" type="int"> diff --git a/ui/base/ime/input_method_auralinux.cc b/ui/base/ime/input_method_auralinux.cc index ccfb7be..4248975 100644 --- a/ui/base/ime/input_method_auralinux.cc +++ b/ui/base/ime/input_method_auralinux.cc @@ -248,6 +248,10 @@ void InputMethodAuraLinux::OnCaretBoundsChanged(const TextInputClient* client) { return; NotifyTextInputCaretBoundsChanged(client); context_->SetCursorLocation(GetTextInputClient()->GetCaretBounds()); + + if (!IsTextInputTypeNone() && text_input_type_ != TEXT_INPUT_TYPE_PASSWORD && + GetEngine()) + GetEngine()->SetCompositionBounds(GetCompositionBounds(client)); } void InputMethodAuraLinux::CancelComposition(const TextInputClient* client) { diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc index df0cb11..d935889 100644 --- a/ui/base/ime/input_method_base.cc +++ b/ui/base/ime/input_method_base.cc @@ -131,4 +131,21 @@ void InputMethodBase::SetFocusedTextInputClientInternal( NotifyTextInputStateChanged(text_input_client_); } +std::vector<gfx::Rect> InputMethodBase::GetCompositionBounds( + const TextInputClient* client) { + std::vector<gfx::Rect> bounds; + if (client->HasCompositionText()) { + uint32_t i = 0; + gfx::Rect rect; + while (client->GetCompositionCharacterBounds(i++, &rect)) + bounds.push_back(rect); + } else { + // For case of no composition at present, use caret bounds which is required + // by the IME extension for certain features (e.g. physical keyboard + // auto-correct). + bounds.push_back(client->GetCaretBounds()); + } + return bounds; +} + } // namespace ui diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h index e334611..432a80f 100644 --- a/ui/base/ime/input_method_base.h +++ b/ui/base/ime/input_method_base.h @@ -5,6 +5,8 @@ #ifndef UI_BASE_IME_INPUT_METHOD_BASE_H_ #define UI_BASE_IME_INPUT_METHOD_BASE_H_ +#include <vector> + #include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -84,6 +86,9 @@ class UI_BASE_IME_EXPORT InputMethodBase // |client| which is the text input client with focus. void NotifyTextInputCaretBoundsChanged(const TextInputClient* client); + // Gets the bounds of the composition text or cursor in |client|. + std::vector<gfx::Rect> GetCompositionBounds(const TextInputClient* client); + private: void SetFocusedTextInputClientInternal(TextInputClient* client); diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 5eaf021..72a3048 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc @@ -169,33 +169,24 @@ void InputMethodChromeOS::OnCaretBoundsChanged(const TextInputClient* client) { // The current text input type should not be NONE if |context_| is focused. DCHECK(client == GetTextInputClient()); DCHECK(!IsTextInputTypeNone()); - const gfx::Rect caret_rect = client->GetCaretBounds(); - - gfx::Rect composition_head; - std::vector<gfx::Rect> rects; - if (client->HasCompositionText()) { - uint32_t i = 0; - gfx::Rect rect; - while (client->GetCompositionCharacterBounds(i++, &rect)) - rects.push_back(rect); - } - - // Pepper don't support composition bounds, so fallback to caret bounds to - // avoid bad user experience (the IME window moved to upper left corner). - // For case of no composition at present, also use caret bounds which is - // required by the IME extension for certain features (e.g. physical keyboard - // autocorrect). - if (rects.empty()) - rects.push_back(caret_rect); - composition_head = rects[0]; if (GetEngine()) - GetEngine()->SetCompositionBounds(rects); + GetEngine()->SetCompositionBounds(GetCompositionBounds(client)); chromeos::IMECandidateWindowHandlerInterface* candidate_window = ui::IMEBridge::Get()->GetCandidateWindowHandler(); if (!candidate_window) return; + + const gfx::Rect caret_rect = client->GetCaretBounds(); + + // Pepper doesn't support composition bounds, so fall back to caret bounds to + // avoid a bad user experience (the IME window moved to upper left corner). + gfx::Rect composition_head; + if (client->HasCompositionText()) + client->GetCompositionCharacterBounds(0, &composition_head); + else + composition_head = caret_rect; candidate_window->SetCursorBounds(caret_rect, composition_head); gfx::Range text_range; diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc index 0520986..6ac7e6f 100644 --- a/ui/base/ime/input_method_win.cc +++ b/ui/base/ime/input_method_win.cc @@ -235,6 +235,10 @@ void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) { gfx::Rect caret_rect(gfx::Point(window_point.x, window_point.y), screen_bounds.size()); imm32_manager_.UpdateCaretRect(attached_window, caret_rect); + + if (client == GetTextInputClient() && + GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD && GetEngine()) + GetEngine()->SetCompositionBounds(GetCompositionBounds(client)); } void InputMethodWin::CancelComposition(const TextInputClient* client) { |