| Index: ui/views/ime/input_method_bridge.cc
|
| diff --git a/ui/views/ime/input_method_bridge.cc b/ui/views/ime/input_method_bridge.cc
|
| index 5238313031e9dbb703c69df4408f611b050f4126..ea13bd481707e2f7cb6569ebf31c128ed8ab4a1d 100644
|
| --- a/ui/views/ime/input_method_bridge.cc
|
| +++ b/ui/views/ime/input_method_bridge.cc
|
| @@ -5,6 +5,7 @@
|
| #include "ui/views/ime/input_method_bridge.h"
|
|
|
| #include "ui/base/ime/input_method.h"
|
| +#include "ui/base/ime/input_method_observer.h"
|
| #include "ui/events/event.h"
|
| #include "ui/gfx/rect.h"
|
| #include "ui/views/view.h"
|
| @@ -12,6 +13,55 @@
|
|
|
| namespace views {
|
|
|
| +// InputMethodBridge::HostObserver class ---------------------------------------
|
| +
|
| +// An observer class for observing the host input method. When the host input
|
| +// method is destroyed, it will null out the |host_| field on the
|
| +// InputMethodBridge object.
|
| +class InputMethodBridge::HostObserver : public ui::InputMethodObserver {
|
| + public:
|
| + explicit HostObserver(InputMethodBridge* bridge);
|
| + virtual ~HostObserver();
|
| +
|
| + virtual void OnTextInputTypeChanged(
|
| + const ui::TextInputClient* client) OVERRIDE {}
|
| + virtual void OnFocus() OVERRIDE {}
|
| + virtual void OnBlur() OVERRIDE {}
|
| + virtual void OnUntranslatedIMEMessage(
|
| + const base::NativeEvent& event) OVERRIDE {}
|
| + virtual void OnCaretBoundsChanged(
|
| + const ui::TextInputClient* client) OVERRIDE {}
|
| + virtual void OnInputLocaleChanged() OVERRIDE {}
|
| + virtual void OnTextInputStateChanged(
|
| + const ui::TextInputClient* client) OVERRIDE {}
|
| + virtual void OnInputMethodDestroyed(
|
| + const ui::InputMethod* input_method) OVERRIDE;
|
| +
|
| + private:
|
| + InputMethodBridge* bridge_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(HostObserver);
|
| +};
|
| +
|
| +InputMethodBridge::HostObserver::HostObserver(InputMethodBridge* bridge)
|
| + : bridge_(bridge) {
|
| + bridge_->host_->AddObserver(this);
|
| +}
|
| +
|
| +InputMethodBridge::HostObserver::~HostObserver() {
|
| + if (bridge_->host_)
|
| + bridge_->host_->RemoveObserver(this);
|
| +}
|
| +
|
| +void InputMethodBridge::HostObserver::OnInputMethodDestroyed(
|
| + const ui::InputMethod* input_method) {
|
| + DCHECK_EQ(bridge_->host_, input_method);
|
| + bridge_->host_->RemoveObserver(this);
|
| + bridge_->host_ = NULL;
|
| +}
|
| +
|
| +// InputMethodBridge class -----------------------------------------------------
|
| +
|
| InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate,
|
| ui::InputMethod* host,
|
| bool shared_input_method)
|
| @@ -19,6 +69,8 @@ InputMethodBridge::InputMethodBridge(internal::InputMethodDelegate* delegate,
|
| shared_input_method_(shared_input_method) {
|
| DCHECK(host_);
|
| SetDelegate(delegate);
|
| +
|
| + host_observer_.reset(new HostObserver(this));
|
| }
|
|
|
| InputMethodBridge::~InputMethodBridge() {
|
| @@ -28,10 +80,15 @@ InputMethodBridge::~InputMethodBridge() {
|
| // this and go into |widget_|. NULL out |widget_| so we don't attempt to use
|
| // it.
|
| DetachFromWidget();
|
| - host_->DetachTextInputClient(this);
|
| +
|
| + // Host input method might have been destroyed at this point.
|
| + if (host_)
|
| + host_->DetachTextInputClient(this);
|
| }
|
|
|
| void InputMethodBridge::OnFocus() {
|
| + DCHECK(host_);
|
| +
|
| // Direct the shared IME to send TextInputClient messages to |this| object.
|
| if (shared_input_method_ || !host_->GetTextInputClient())
|
| host_->SetFocusedTextInputClient(this);
|
| @@ -43,6 +100,8 @@ void InputMethodBridge::OnFocus() {
|
| }
|
|
|
| void InputMethodBridge::OnBlur() {
|
| + DCHECK(host_);
|
| +
|
| if (HasCompositionText()) {
|
| ConfirmCompositionText();
|
| host_->CancelComposition(this);
|
| @@ -54,6 +113,8 @@ void InputMethodBridge::OnBlur() {
|
|
|
| bool InputMethodBridge::OnUntranslatedIMEMessage(const base::NativeEvent& event,
|
| NativeEventResult* result) {
|
| + DCHECK(host_);
|
| +
|
| return host_->OnUntranslatedIMEMessage(event, result);
|
| }
|
|
|
| @@ -66,38 +127,54 @@ void InputMethodBridge::DispatchKeyEvent(const ui::KeyEvent& key) {
|
| }
|
|
|
| void InputMethodBridge::OnTextInputTypeChanged(View* view) {
|
| + DCHECK(host_);
|
| +
|
| if (IsViewFocused(view))
|
| host_->OnTextInputTypeChanged(this);
|
| InputMethodBase::OnTextInputTypeChanged(view);
|
| }
|
|
|
| void InputMethodBridge::OnCaretBoundsChanged(View* view) {
|
| + DCHECK(host_);
|
| +
|
| if (IsViewFocused(view) && !IsTextInputTypeNone())
|
| host_->OnCaretBoundsChanged(this);
|
| }
|
|
|
| void InputMethodBridge::CancelComposition(View* view) {
|
| + DCHECK(host_);
|
| +
|
| if (IsViewFocused(view))
|
| host_->CancelComposition(this);
|
| }
|
|
|
| void InputMethodBridge::OnInputLocaleChanged() {
|
| - return host_->OnInputLocaleChanged();
|
| + DCHECK(host_);
|
| +
|
| + host_->OnInputLocaleChanged();
|
| }
|
|
|
| std::string InputMethodBridge::GetInputLocale() {
|
| + DCHECK(host_);
|
| +
|
| return host_->GetInputLocale();
|
| }
|
|
|
| base::i18n::TextDirection InputMethodBridge::GetInputTextDirection() {
|
| + DCHECK(host_);
|
| +
|
| return host_->GetInputTextDirection();
|
| }
|
|
|
| bool InputMethodBridge::IsActive() {
|
| + DCHECK(host_);
|
| +
|
| return host_->IsActive();
|
| }
|
|
|
| bool InputMethodBridge::IsCandidatePopupOpen() const {
|
| + DCHECK(host_);
|
| +
|
| return host_->IsCandidatePopupOpen();
|
| }
|
|
|
|
|