summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-04 23:47:16 +0000
committeryukishiino@chromium.org <yukishiino@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-09-04 23:47:16 +0000
commit64c15a3b3ac83e94f23c4e569e28f31bf95175ca (patch)
treecb3a4d5b69a18ce95a9f257fd5318bc05fb6038c
parent4945bdc6496fdc0bb4af71978f2e95a9731bbd9e (diff)
downloadchromium_src-64c15a3b3ac83e94f23c4e569e28f31bf95175ca.zip
chromium_src-64c15a3b3ac83e94f23c4e569e28f31bf95175ca.tar.gz
chromium_src-64c15a3b3ac83e94f23c4e569e28f31bf95175ca.tar.bz2
Makes sure that an input method doesn't reference to a destroyed object.
This CL makes sure that an input method never reference to a destroyed object. We're not 100% sure why Issue 280219 is happening, but it seems a destroyed object is referenced from an input method. For render_widget_host_view_win.cc, there is no need to check the focus. Even if it's not focused, the object going to be destroyed should be removed from the TSFBridge. BUG=280219 TEST=none Review URL: https://chromiumcodereview.appspot.com/23478020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221302 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc7
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc2
-rw-r--r--ui/base/ime/dummy_input_method.cc3
-rw-r--r--ui/base/ime/dummy_input_method.h1
-rw-r--r--ui/base/ime/fake_input_method.cc8
-rw-r--r--ui/base/ime/fake_input_method.h1
-rw-r--r--ui/base/ime/input_method.h7
-rw-r--r--ui/base/ime/input_method_base.cc9
-rw-r--r--ui/base/ime/input_method_base.h1
-rw-r--r--ui/base/ime/mock_input_method.cc5
-rw-r--r--ui/base/ime/mock_input_method.h1
11 files changed, 43 insertions, 2 deletions
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 0f10b92..f78efef 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2464,6 +2464,13 @@ void RenderWidgetHostViewAura::OnWindowDestroying() {
LPARAM lparam = reinterpret_cast<LPARAM>(this);
EnumChildWindows(parent, WindowDestroyingCallback, lparam);
#endif
+
+ // Make sure that the input method no longer references to this object before
+ // this object is removed from the root window (i.e. this object loses access
+ // to the input method).
+ ui::InputMethod* input_method = GetInputMethod();
+ if (input_method)
+ input_method->DetachTextInputClient(this);
}
void RenderWidgetHostViewAura::OnWindowDestroyed() {
diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc
index b13970b..5d5eeb4 100644
--- a/content/browser/renderer_host/render_widget_host_view_win.cc
+++ b/content/browser/renderer_host/render_widget_host_view_win.cc
@@ -809,7 +809,7 @@ bool RenderWidgetHostViewWin::CanSubscribeFrame() const {
void RenderWidgetHostViewWin::WillWmDestroy() {
CleanupCompositorWindow();
- if (base::win::IsTSFAwareRequired() && GetFocus() == m_hWnd)
+ if (base::win::IsTSFAwareRequired())
ui::TSFBridge::GetInstance()->RemoveFocusedClient(this);
}
diff --git a/ui/base/ime/dummy_input_method.cc b/ui/base/ime/dummy_input_method.cc
index b9f6941..b35313d 100644
--- a/ui/base/ime/dummy_input_method.cc
+++ b/ui/base/ime/dummy_input_method.cc
@@ -32,6 +32,9 @@ bool DummyInputMethod::OnUntranslatedIMEMessage(const base::NativeEvent& event,
void DummyInputMethod::SetFocusedTextInputClient(TextInputClient* client) {
}
+void DummyInputMethod::DetachTextInputClient(TextInputClient* client) {
+}
+
TextInputClient* DummyInputMethod::GetTextInputClient() const {
return NULL;
}
diff --git a/ui/base/ime/dummy_input_method.h b/ui/base/ime/dummy_input_method.h
index 165bc52..0e40c18 100644
--- a/ui/base/ime/dummy_input_method.h
+++ b/ui/base/ime/dummy_input_method.h
@@ -25,6 +25,7 @@ class DummyInputMethod : public InputMethod {
virtual bool OnUntranslatedIMEMessage(
const base::NativeEvent& event, NativeEventResult* result) OVERRIDE;
virtual void SetFocusedTextInputClient(TextInputClient* client) OVERRIDE;
+ virtual void DetachTextInputClient(TextInputClient* client) OVERRIDE;
virtual TextInputClient* GetTextInputClient() const OVERRIDE;
virtual bool DispatchKeyEvent(const base::NativeEvent& event) OVERRIDE;
virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent& event) OVERRIDE;
diff --git a/ui/base/ime/fake_input_method.cc b/ui/base/ime/fake_input_method.cc
index 15f1283..952108c 100644
--- a/ui/base/ime/fake_input_method.cc
+++ b/ui/base/ime/fake_input_method.cc
@@ -55,6 +55,14 @@ void FakeInputMethod::SetFocusedTextInputClient(TextInputClient* client) {
OnTextInputStateChanged(client));
}
+void FakeInputMethod::DetachTextInputClient(TextInputClient* client) {
+ if (text_input_client_ == client) {
+ text_input_client_ = NULL;
+ FOR_EACH_OBSERVER(InputMethodObserver, observers_,
+ OnTextInputStateChanged(client));
+ }
+}
+
TextInputClient* FakeInputMethod::GetTextInputClient() const {
return text_input_client_;
}
diff --git a/ui/base/ime/fake_input_method.h b/ui/base/ime/fake_input_method.h
index e80d2bc..9aca97c 100644
--- a/ui/base/ime/fake_input_method.h
+++ b/ui/base/ime/fake_input_method.h
@@ -34,6 +34,7 @@ class UI_EXPORT FakeInputMethod : NON_EXPORTED_BASE(public InputMethod) {
virtual bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
NativeEventResult* result) OVERRIDE;
virtual void SetFocusedTextInputClient(TextInputClient* client) OVERRIDE;
+ virtual void DetachTextInputClient(TextInputClient* client) OVERRIDE;
virtual TextInputClient* GetTextInputClient() const OVERRIDE;
virtual bool DispatchKeyEvent(const base::NativeEvent& native_event) OVERRIDE;
virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent& event) OVERRIDE;
diff --git a/ui/base/ime/input_method.h b/ui/base/ime/input_method.h
index 0d4046f..4deaa54 100644
--- a/ui/base/ime/input_method.h
+++ b/ui/base/ime/input_method.h
@@ -83,9 +83,14 @@ class InputMethod {
// SetCompositionText(). |client| can be NULL. A gfx::NativeWindow which
// implementes TextInputClient interface, e.g. NWA and RWHVA, should register
// itself by calling the method when it is focused, and unregister itself by
- // calling the metho with NULL when it is unfocused.
+ // calling the method with NULL when it is unfocused.
virtual void SetFocusedTextInputClient(TextInputClient* client) = 0;
+ // Detaches and forgets the |client| regardless of whether it has the focus or
+ // not. This method is meant to be called when the |client| is going to be
+ // destroyed.
+ virtual void DetachTextInputClient(TextInputClient* client) = 0;
+
// Gets the current text input client. Returns NULL when no client is set.
virtual TextInputClient* GetTextInputClient() const = 0;
diff --git a/ui/base/ime/input_method_base.cc b/ui/base/ime/input_method_base.cc
index 23d21ba..1ab7942 100644
--- a/ui/base/ime/input_method_base.cc
+++ b/ui/base/ime/input_method_base.cc
@@ -52,6 +52,15 @@ void InputMethodBase::SetFocusedTextInputClient(TextInputClient* client) {
NotifyTextInputStateChanged(text_input_client_);
}
+void InputMethodBase::DetachTextInputClient(TextInputClient* client) {
+ if (text_input_client_ == client) {
+ OnWillChangeFocusedClient(client, NULL);
+ text_input_client_ = NULL;
+ OnDidChangeFocusedClient(client, NULL);
+ NotifyTextInputStateChanged(text_input_client_);
+ }
+}
+
TextInputClient* InputMethodBase::GetTextInputClient() const {
return system_toplevel_window_focused_ ? text_input_client_ : NULL;
}
diff --git a/ui/base/ime/input_method_base.h b/ui/base/ime/input_method_base.h
index 655fd4a..a3a106e 100644
--- a/ui/base/ime/input_method_base.h
+++ b/ui/base/ime/input_method_base.h
@@ -37,6 +37,7 @@ class UI_EXPORT InputMethodBase : NON_EXPORTED_BASE(public InputMethod) {
virtual void OnFocus() OVERRIDE;
virtual void OnBlur() OVERRIDE;
virtual void SetFocusedTextInputClient(TextInputClient* client) OVERRIDE;
+ virtual void DetachTextInputClient(TextInputClient* client) OVERRIDE;
virtual TextInputClient* GetTextInputClient() const OVERRIDE;
// If a derived class overrides this method, it should call parent's
diff --git a/ui/base/ime/mock_input_method.cc b/ui/base/ime/mock_input_method.cc
index aed83c2..58134fa 100644
--- a/ui/base/ime/mock_input_method.cc
+++ b/ui/base/ime/mock_input_method.cc
@@ -24,6 +24,11 @@ void MockInputMethod::SetFocusedTextInputClient(TextInputClient* client) {
OnTextInputTypeChanged(client);
}
+void MockInputMethod::DetachTextInputClient(TextInputClient* client) {
+ if (text_input_client_ == client)
+ text_input_client_ = NULL;
+}
+
TextInputClient* MockInputMethod::GetTextInputClient() const {
return text_input_client_;
}
diff --git a/ui/base/ime/mock_input_method.h b/ui/base/ime/mock_input_method.h
index fdeff5e..1d7922f 100644
--- a/ui/base/ime/mock_input_method.h
+++ b/ui/base/ime/mock_input_method.h
@@ -49,6 +49,7 @@ class UI_EXPORT MockInputMethod : NON_EXPORTED_BASE(public InputMethod) {
virtual bool OnUntranslatedIMEMessage(const base::NativeEvent& event,
NativeEventResult* result) OVERRIDE;
virtual void SetFocusedTextInputClient(TextInputClient* client) OVERRIDE;
+ virtual void DetachTextInputClient(TextInputClient* client) OVERRIDE;
virtual TextInputClient* GetTextInputClient() const OVERRIDE;
virtual bool DispatchKeyEvent(const base::NativeEvent& native_event) OVERRIDE;
virtual bool DispatchFabricatedKeyEvent(const ui::KeyEvent& event) OVERRIDE;