summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryukawa@chromium.org <yukawa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 13:42:47 +0000
committeryukawa@chromium.org <yukawa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 13:42:47 +0000
commit364fb6e517fc4fbc8196a4afba4f77b3d5300c3e (patch)
tree5ef6314eb44689e8803e9e6d52dbd040cd26a2d6
parent61346e7350d8efd4589c735a75ed962a3f4bcb51 (diff)
downloadchromium_src-364fb6e517fc4fbc8196a4afba4f77b3d5300c3e.zip
chromium_src-364fb6e517fc4fbc8196a4afba4f77b3d5300c3e.tar.gz
chromium_src-364fb6e517fc4fbc8196a4afba4f77b3d5300c3e.tar.bz2
Add InputMethodObserver support into InputMethodBase
This is a preparation CL to fix issue 164964. Following observer callbacks are defined but not yet supported by ui::InputMethodBase and its sub classes. - InputMethodObserver::OnCaretBoundsChanged - InputMethodObserver::OnInputLocaleChanged This CL makes these callbacks functional for each sub class of ui::InputMethodBase. BUG=164964 TEST=ui_unittests --gtest_filter=InputMethodBaseTest.* Review URL: https://codereview.chromium.org/48393003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231563 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ui/base/ime/input_method_base.cc14
-rw-r--r--ui/base/ime/input_method_base.h2
-rw-r--r--ui/base/ime/input_method_base_unittest.cc163
-rw-r--r--ui/base/ime/input_method_ibus.cc120
-rw-r--r--ui/base/ime/input_method_ibus.h4
-rw-r--r--ui/base/ime/input_method_imm32.cc35
-rw-r--r--ui/base/ime/input_method_linux_x11.cc14
-rw-r--r--ui/base/ime/input_method_tsf.cc1
-rw-r--r--ui/base/ime/input_method_win.cc1
9 files changed, 243 insertions, 111 deletions
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index f211198..302b54d 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -74,6 +74,20 @@ void InputMethodBase::OnTextInputTypeChanged(const TextInputClient* client) {
NotifyTextInputStateChanged(client);
}
+void InputMethodBase::OnCaretBoundsChanged(const TextInputClient* client) {
+ if (!IsTextInputClientFocused(client))
+ return;
+ FOR_EACH_OBSERVER(InputMethodObserver,
+ observer_list_,
+ OnCaretBoundsChanged(client));
+}
+
+void InputMethodBase::OnInputLocaleChanged() {
+ FOR_EACH_OBSERVER(InputMethodObserver,
+ observer_list_,
+ OnInputLocaleChanged());
+}
+
TextInputType InputMethodBase::GetTextInputType() const {
TextInputClient* client = GetTextInputClient();
return client ? client->GetTextInputType() : TEXT_INPUT_TYPE_NONE;
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h
index 665070a..07104f9 100644
--- a/ui/base/ime/input_method_base.h
+++ b/ui/base/ime/input_method_base.h
@@ -45,6 +45,8 @@ class UI_EXPORT InputMethodBase : NON_EXPORTED_BASE(public InputMethod) {
// If a derived class overrides this method, it should call parent's
// implementation.
virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE;
+ virtual void OnCaretBoundsChanged(const TextInputClient* client) OVERRIDE;
+ virtual void OnInputLocaleChanged() OVERRIDE;
virtual TextInputType GetTextInputType() const OVERRIDE;
virtual TextInputMode GetTextInputMode() const OVERRIDE;
diff --git a/ui/base/ime/input_method_base_unittest.cc b/ui/base/ime/input_method_base_unittest.cc
index 5d4447f..48623dd 100644
--- a/ui/base/ime/input_method_base_unittest.cc
+++ b/ui/base/ime/input_method_base_unittest.cc
@@ -110,13 +110,11 @@ class ClientChangeVerifier {
DISALLOW_COPY_AND_ASSIGN(ClientChangeVerifier);
};
-class MockInputMethodBase : public InputMethodBase {
+class SimpleMockInputMethodBase : public InputMethodBase {
public:
- // Note: this class does not take the ownership of |verifier|.
- explicit MockInputMethodBase(ClientChangeVerifier* verifier)
- : verifier_(verifier) {
+ SimpleMockInputMethodBase() {
}
- virtual ~MockInputMethodBase() {
+ virtual ~SimpleMockInputMethodBase() {
}
private:
@@ -132,13 +130,9 @@ class MockInputMethodBase : public InputMethodBase {
virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent&) OVERRIDE {
return false;
}
- virtual void OnCaretBoundsChanged(const TextInputClient* clien) OVERRIDE {
- }
- virtual void CancelComposition(const TextInputClient* clien) OVERRIDE {
+ virtual void CancelComposition(const TextInputClient* client) OVERRIDE {
}
- virtual void OnInputLocaleChanged() OVERRIDE {
- }
- virtual std::string GetInputLocale() OVERRIDE {
+ virtual std::string GetInputLocale() OVERRIDE{
return "";
}
virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE {
@@ -150,7 +144,19 @@ class MockInputMethodBase : public InputMethodBase {
virtual bool IsCandidatePopupOpen() const OVERRIDE {
return false;
}
+ DISALLOW_COPY_AND_ASSIGN(SimpleMockInputMethodBase);
+};
+
+class MockInputMethodBase : public SimpleMockInputMethodBase {
+ public:
+ // Note: this class does not take the ownership of |verifier|.
+ explicit MockInputMethodBase(ClientChangeVerifier* verifier)
+ : verifier_(verifier) {
+ }
+ virtual ~MockInputMethodBase() {
+ }
+ private:
// Overriden from InputMethodBase.
virtual void OnWillChangeFocusedClient(TextInputClient* focused_before,
TextInputClient* focused) OVERRIDE {
@@ -166,33 +172,65 @@ class MockInputMethodBase : public InputMethodBase {
DISALLOW_COPY_AND_ASSIGN(MockInputMethodBase);
};
-class MockInputMethodObserver : public InputMethodObserver {
+class SimpleMockInputMethodObserver : public InputMethodObserver {
public:
- // Note: this class does not take the ownership of |verifier|.
- explicit MockInputMethodObserver(ClientChangeVerifier* verifier)
- : verifier_(verifier) {
+ SimpleMockInputMethodObserver()
+ : on_caret_bounds_changed_(0),
+ on_input_locale_changed_(0) {
}
- virtual ~MockInputMethodObserver() {
+ virtual ~SimpleMockInputMethodObserver() {
+ }
+ void Reset() {
+ on_caret_bounds_changed_ = 0;
+ on_input_locale_changed_ = 0;
+ }
+ size_t on_caret_bounds_changed() const {
+ return on_caret_bounds_changed_;
+ }
+ size_t on_input_locale_changed() const {
+ return on_input_locale_changed_;
}
private:
- virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE {
+ // Overriden from InputMethodObserver.
+ virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE{
}
- virtual void OnFocus() OVERRIDE {
+ virtual void OnFocus() OVERRIDE{
}
- virtual void OnBlur() OVERRIDE {
+ virtual void OnBlur() OVERRIDE{
}
virtual void OnUntranslatedIMEMessage(
- const base::NativeEvent& event) OVERRIDE {
+ const base::NativeEvent& event) OVERRIDE{
}
- virtual void OnCaretBoundsChanged(const TextInputClient* client) OVERRIDE {
+ virtual void OnCaretBoundsChanged(const TextInputClient* client) OVERRIDE{
+ ++on_caret_bounds_changed_;
}
- virtual void OnInputLocaleChanged() OVERRIDE {
+ virtual void OnInputLocaleChanged() OVERRIDE{
+ ++on_input_locale_changed_;
}
- virtual void OnTextInputStateChanged(const TextInputClient* client) OVERRIDE {
- verifier_->OnTextInputStateChanged(client);
+ virtual void OnTextInputStateChanged(const TextInputClient* client) OVERRIDE{
}
- virtual void OnInputMethodDestroyed(const InputMethod* client) OVERRIDE {
+ virtual void OnInputMethodDestroyed(const InputMethod* client) OVERRIDE{
+ }
+
+ size_t on_caret_bounds_changed_;
+ size_t on_input_locale_changed_;
+ DISALLOW_COPY_AND_ASSIGN(SimpleMockInputMethodObserver);
+};
+
+class MockInputMethodObserver : public SimpleMockInputMethodObserver {
+ public:
+ // Note: this class does not take the ownership of |verifier|.
+ explicit MockInputMethodObserver(ClientChangeVerifier* verifier)
+ : verifier_(verifier) {
+ }
+ virtual ~MockInputMethodObserver() {
+ }
+
+ private:
+ // Overriden from SimpleMockInputMethodObserver.
+ virtual void OnTextInputStateChanged(const TextInputClient* client) OVERRIDE{
+ verifier_->OnTextInputStateChanged(client);
}
ClientChangeVerifier* verifier_;
@@ -379,5 +417,80 @@ TEST(InputMethodBaseTest, SetStickyFocusedTextInputClient) {
}
}
+TEST(InputMethodBaseTest, OnCaretBoundsChanged) {
+ DummyTextInputClient text_input_client;
+ DummyTextInputClient text_input_client_the_other;
+
+ SimpleMockInputMethodBase input_method;
+ SimpleMockInputMethodObserver input_method_observer;
+ InputMethodScopedObserver scoped_observer(&input_method_observer);
+ scoped_observer.Add(&input_method);
+
+ // Assume that the top-level-widget gains focus.
+ input_method.OnFocus();
+
+ {
+ SCOPED_TRACE("OnCaretBoundsChanged callback must not be fired when no text "
+ "input client is focused");
+ ASSERT_EQ(NULL, input_method.GetTextInputClient());
+
+ input_method_observer.Reset();
+ input_method.OnCaretBoundsChanged(&text_input_client);
+ EXPECT_EQ(0u, input_method_observer.on_caret_bounds_changed());
+ input_method.OnCaretBoundsChanged(NULL);
+ EXPECT_EQ(0u, input_method_observer.on_caret_bounds_changed());
+ }
+
+ {
+ SCOPED_TRACE("OnCaretBoundsChanged callback must be fired when and only "
+ "the event is notified from the focused text input client");
+
+ input_method.SetFocusedTextInputClient(&text_input_client);
+ ASSERT_EQ(&text_input_client, input_method.GetTextInputClient());
+
+ // Must fire the event
+ input_method_observer.Reset();
+ input_method.OnCaretBoundsChanged(&text_input_client);
+ EXPECT_EQ(1u, input_method_observer.on_caret_bounds_changed());
+
+ // Must not fire the event
+ input_method_observer.Reset();
+ input_method.OnCaretBoundsChanged(NULL);
+ EXPECT_EQ(0u, input_method_observer.on_caret_bounds_changed());
+
+ // Must not fire the event
+ input_method_observer.Reset();
+ input_method.OnCaretBoundsChanged(&text_input_client_the_other);
+ EXPECT_EQ(0u, input_method_observer.on_caret_bounds_changed());
+ }
+}
+
+TEST(InputMethodBaseTest, OnInputLocaleChanged) {
+ DummyTextInputClient text_input_client;
+
+ SimpleMockInputMethodBase input_method;
+ SimpleMockInputMethodObserver input_method_observer;
+ InputMethodScopedObserver scoped_observer(&input_method_observer);
+ scoped_observer.Add(&input_method);
+
+ // Assume that the top-level-widget gains focus.
+ input_method.OnFocus();
+
+ {
+ SCOPED_TRACE("OnInputLocaleChanged callback can be fired even when no text "
+ "input client is focused");
+ ASSERT_EQ(NULL, input_method.GetTextInputClient());
+
+ input_method_observer.Reset();
+ input_method.OnInputLocaleChanged();
+ EXPECT_EQ(1u, input_method_observer.on_input_locale_changed());
+
+ input_method.SetFocusedTextInputClient(&text_input_client);
+ input_method_observer.Reset();
+ input_method.OnInputLocaleChanged();
+ EXPECT_EQ(1u, input_method_observer.on_input_locale_changed());
+ }
+}
+
} // namespace
} // namespace ui
diff --git a/ui/base/ime/input_method_ibus.cc b/ui/base/ime/input_method_ibus.cc
index d712463..c0bfed1 100644
--- a/ui/base/ime/input_method_ibus.cc
+++ b/ui/base/ime/input_method_ibus.cc
@@ -234,61 +234,8 @@ void InputMethodIBus::OnTextInputTypeChanged(const TextInputClient* client) {
}
void InputMethodIBus::OnCaretBoundsChanged(const TextInputClient* client) {
- if (!context_focused_ || !IsTextInputClientFocused(client))
- return;
-
- // The current text input type should not be NONE if |context_| is focused.
- DCHECK(!IsTextInputTypeNone());
- const gfx::Rect rect = GetTextInputClient()->GetCaretBounds();
-
- gfx::Rect composition_head;
- if (!GetTextInputClient()->GetCompositionCharacterBounds(0,
- &composition_head)) {
- composition_head = rect;
- }
-
- chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window =
- chromeos::IBusBridge::Get()->GetCandidateWindowHandler();
- if (!candidate_window)
- return;
- candidate_window->SetCursorLocation(
- GfxRectToIBusRect(rect),
- GfxRectToIBusRect(composition_head));
-
- gfx::Range text_range;
- gfx::Range selection_range;
- string16 surrounding_text;
- if (!GetTextInputClient()->GetTextRange(&text_range) ||
- !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) ||
- !GetTextInputClient()->GetSelectionRange(&selection_range)) {
- previous_surrounding_text_.clear();
- previous_selection_range_ = gfx::Range::InvalidRange();
- return;
- }
-
- if (previous_selection_range_ == selection_range &&
- previous_surrounding_text_ == surrounding_text)
- return;
-
- previous_selection_range_ = selection_range;
- previous_surrounding_text_ = surrounding_text;
-
- if (!selection_range.IsValid()) {
- // TODO(nona): Ideally selection_range should not be invalid.
- // TODO(nona): If javascript changes the focus on page loading, even (0,0)
- // can not be obtained. Need investigation.
- return;
- }
-
- // Here SetSurroundingText accepts relative position of |surrounding_text|, so
- // we have to convert |selection_range| from node coordinates to
- // |surrounding_text| coordinates.
- if (!GetEngine())
- return;
- GetEngine()->SetSurroundingText(
- UTF16ToUTF8(surrounding_text),
- selection_range.start() - text_range.start(),
- selection_range.end() - text_range.start());
+ OnCaretBoundsChangedInternal(client);
+ InputMethodBase::OnCaretBoundsChanged(client);
}
void InputMethodIBus::CancelComposition(const TextInputClient* client) {
@@ -296,10 +243,6 @@ void InputMethodIBus::CancelComposition(const TextInputClient* client) {
ResetContext();
}
-void InputMethodIBus::OnInputLocaleChanged() {
- // Not supported.
-}
-
std::string InputMethodIBus::GetInputLocale() {
// Not supported.
return "";
@@ -806,4 +749,63 @@ void InputMethodIBus::ExtractCompositionText(
}
}
+void InputMethodIBus::OnCaretBoundsChangedInternal(
+ const TextInputClient* client) {
+ if (!context_focused_ || !IsTextInputClientFocused(client))
+ return;
+
+ // The current text input type should not be NONE if |context_| is focused.
+ DCHECK(!IsTextInputTypeNone());
+ const gfx::Rect rect = GetTextInputClient()->GetCaretBounds();
+
+ gfx::Rect composition_head;
+ if (!GetTextInputClient()->GetCompositionCharacterBounds(0,
+ &composition_head)) {
+ composition_head = rect;
+ }
+
+ chromeos::IBusPanelCandidateWindowHandlerInterface* candidate_window =
+ chromeos::IBusBridge::Get()->GetCandidateWindowHandler();
+ if (!candidate_window)
+ return;
+ candidate_window->SetCursorLocation(
+ GfxRectToIBusRect(rect),
+ GfxRectToIBusRect(composition_head));
+
+ gfx::Range text_range;
+ gfx::Range selection_range;
+ string16 surrounding_text;
+ if (!GetTextInputClient()->GetTextRange(&text_range) ||
+ !GetTextInputClient()->GetTextFromRange(text_range, &surrounding_text) ||
+ !GetTextInputClient()->GetSelectionRange(&selection_range)) {
+ previous_surrounding_text_.clear();
+ previous_selection_range_ = gfx::Range::InvalidRange();
+ return;
+ }
+
+ if (previous_selection_range_ == selection_range &&
+ previous_surrounding_text_ == surrounding_text)
+ return;
+
+ previous_selection_range_ = selection_range;
+ previous_surrounding_text_ = surrounding_text;
+
+ if (!selection_range.IsValid()) {
+ // TODO(nona): Ideally selection_range should not be invalid.
+ // TODO(nona): If javascript changes the focus on page loading, even (0,0)
+ // can not be obtained. Need investigation.
+ return;
+ }
+
+ // Here SetSurroundingText accepts relative position of |surrounding_text|, so
+ // we have to convert |selection_range| from node coordinates to
+ // |surrounding_text| coordinates.
+ if (!GetEngine())
+ return;
+ GetEngine()->SetSurroundingText(
+ UTF16ToUTF8(surrounding_text),
+ selection_range.start() - text_range.start(),
+ selection_range.end() - text_range.start());
+}
+
} // namespace ui
diff --git a/ui/base/ime/input_method_ibus.h b/ui/base/ime/input_method_ibus.h
index 1f0b194..b4aecde 100644
--- a/ui/base/ime/input_method_ibus.h
+++ b/ui/base/ime/input_method_ibus.h
@@ -47,7 +47,6 @@ class UI_EXPORT InputMethodIBus
virtual void OnTextInputTypeChanged(const TextInputClient* client) OVERRIDE;
virtual void OnCaretBoundsChanged(const TextInputClient* client) OVERRIDE;
virtual void CancelComposition(const TextInputClient* client) OVERRIDE;
- virtual void OnInputLocaleChanged() OVERRIDE;
virtual std::string GetInputLocale() OVERRIDE;
virtual base::i18n::TextDirection GetInputTextDirection() OVERRIDE;
virtual bool IsActive() OVERRIDE;
@@ -139,6 +138,9 @@ class UI_EXPORT InputMethodIBus
uint32 ibus_keyval, uint32 ibus_keycode,
uint32 ibus_state, bool is_handled);
+ // Processes a caret bounds changed event.
+ void OnCaretBoundsChangedInternal(const TextInputClient* client);
+
// All pending key events. Note: we do not own these object, we just save
// pointers to these object so that we can abandon them when necessary.
// They will be deleted in ProcessKeyEventDone().
diff --git a/ui/base/ime/input_method_imm32.cc b/ui/base/ime/input_method_imm32.cc
index 4f17ea9..ca02fa3 100644
--- a/ui/base/ime/input_method_imm32.cc
+++ b/ui/base/ime/input_method_imm32.cc
@@ -94,26 +94,23 @@ void InputMethodIMM32::OnTextInputTypeChanged(const TextInputClient* client) {
}
void InputMethodIMM32::OnCaretBoundsChanged(const TextInputClient* client) {
- if (!enabled_ || !IsTextInputClientFocused(client) ||
- !IsWindowFocused(client)) {
- return;
+ if (enabled_ && IsTextInputClientFocused(client) && IsWindowFocused(client)) {
+ // The current text input type should not be NONE if |client| is focused.
+ DCHECK(!IsTextInputTypeNone());
+ gfx::Rect screen_bounds(GetTextInputClient()->GetCaretBounds());
+
+ HWND attached_window = GetAttachedWindowHandle(client);
+ // TODO(ime): see comment in TextInputClient::GetCaretBounds(), this
+ // conversion shouldn't be necessary.
+ RECT r = {};
+ GetClientRect(attached_window, &r);
+ POINT window_point = { screen_bounds.x(), screen_bounds.y() };
+ ScreenToClient(attached_window, &window_point);
+ gfx::Rect caret_rect(gfx::Point(window_point.x, window_point.y),
+ screen_bounds.size());
+ imm32_manager_.UpdateCaretRect(attached_window, caret_rect);
}
-
- // The current text input type should not be NONE if |client| is focused.
- DCHECK(!IsTextInputTypeNone());
- gfx::Rect screen_bounds(GetTextInputClient()->GetCaretBounds());
-
- HWND attached_window = GetAttachedWindowHandle(client);
- // TODO(ime): see comment in TextInputClient::GetCaretBounds(), this
- // conversion shouldn't be necessary.
- RECT r;
- GetClientRect(attached_window, &r);
- POINT window_point = { screen_bounds.x(), screen_bounds.y() };
- ScreenToClient(attached_window, &window_point);
- imm32_manager_.UpdateCaretRect(
- attached_window,
- gfx::Rect(gfx::Point(window_point.x, window_point.y),
- screen_bounds.size()));
+ InputMethodWin::OnCaretBoundsChanged(client);
}
void InputMethodIMM32::CancelComposition(const TextInputClient* client) {
diff --git a/ui/base/ime/input_method_linux_x11.cc b/ui/base/ime/input_method_linux_x11.cc
index 415a7bd..5973761 100644
--- a/ui/base/ime/input_method_linux_x11.cc
+++ b/ui/base/ime/input_method_linux_x11.cc
@@ -110,13 +110,12 @@ void InputMethodLinuxX11::OnTextInputTypeChanged(
InputMethodBase::OnTextInputTypeChanged(client);
}
-void InputMethodLinuxX11::OnCaretBoundsChanged(
- const TextInputClient* client) {
- if (!IsTextInputClientFocused(client))
- return;
-
- input_method_context_->OnCaretBoundsChanged(
- GetTextInputClient()->GetCaretBounds());
+void InputMethodLinuxX11::OnCaretBoundsChanged(const TextInputClient* client) {
+ if (IsTextInputClientFocused(client)) {
+ input_method_context_->OnCaretBoundsChanged(
+ GetTextInputClient()->GetCaretBounds());
+ }
+ InputMethodBase::OnCaretBoundsChanged(client);
}
void InputMethodLinuxX11::CancelComposition(const TextInputClient* client) {
@@ -128,6 +127,7 @@ void InputMethodLinuxX11::CancelComposition(const TextInputClient* client) {
}
void InputMethodLinuxX11::OnInputLocaleChanged() {
+ InputMethodBase::OnInputLocaleChanged();
}
std::string InputMethodLinuxX11::GetInputLocale() {
diff --git a/ui/base/ime/input_method_tsf.cc b/ui/base/ime/input_method_tsf.cc
index aaec2e0..944f977 100644
--- a/ui/base/ime/input_method_tsf.cc
+++ b/ui/base/ime/input_method_tsf.cc
@@ -108,6 +108,7 @@ void InputMethodTSF::OnTextInputTypeChanged(const TextInputClient* client) {
void InputMethodTSF::OnCaretBoundsChanged(const TextInputClient* client) {
if (IsTextInputClientFocused(client) && IsWindowFocused(client))
ui::TSFBridge::GetInstance()->OnTextLayoutChanged();
+ InputMethodWin::OnCaretBoundsChanged(client);
}
void InputMethodTSF::CancelComposition(const TextInputClient* client) {
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc
index 4bb8b6a..adefd889 100644
--- a/ui/base/ime/input_method_win.cc
+++ b/ui/base/ime/input_method_win.cc
@@ -94,6 +94,7 @@ void InputMethodWin::OnInputLocaleChanged() {
locale_ = imm32_manager_.GetInputLanguageName();
direction_ = imm32_manager_.GetTextDirection();
OnInputMethodChanged();
+ InputMethodBase::OnInputLocaleChanged();
}
std::string InputMethodWin::GetInputLocale() {