summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc30
-rw-r--r--chrome/common/extensions/api/input_ime.json14
-rw-r--r--extensions/browser/extension_event_histogram_value.h1
-rw-r--r--tools/metrics/histograms/histograms.xml1
-rw-r--r--ui/base/ime/input_method_auralinux.cc4
-rw-r--r--ui/base/ime/input_method_base.cc17
-rw-r--r--ui/base/ime/input_method_base.h5
-rw-r--r--ui/base/ime/input_method_chromeos.cc31
-rw-r--r--ui/base/ime/input_method_win.cc4
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) {