Commit 695fb334 authored by cpu@chromium.org's avatar cpu@chromium.org

Revert 201479 "Make InputMethodWin TSF-aware."

This is breaking chrome on windows 8, can't relaunch in desktop
see bug

BUG=244453

> Make InputMethodWin TSF-aware.
> 
> This patch set introduces following event handlings
> so that InputMethodWin can work with TSF-based IME.
> - Focus handling (OnFocus/OnBlur)
> - TextInputType handling (OnTextInputTypeChanged)
> - Composition Handling (OnDidChangeFocus/ConfirmCompositionText)
> 
> Basically this is just a quick fix and InputMethodWin
> should be refactored eventually.
> 
> BUG=239690
> TEST=Manually done on Windows 7 with --enable-text-services-framework
> 
> Review URL: https://chromiumcodereview.appspot.com/14698032

TBR=Yukawa@chromium.org

Review URL: https://codereview.chromium.org/15897010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202709 0039d316-1c4b-4281-b951-d872f2087c98
parent 5239f90b
...@@ -38,10 +38,6 @@ void MockTSFBridge::OnTextInputTypeChanged(TextInputClient* client) { ...@@ -38,10 +38,6 @@ void MockTSFBridge::OnTextInputTypeChanged(TextInputClient* client) {
latest_text_input_type_ = client->GetTextInputType(); latest_text_input_type_ = client->GetTextInputType();
} }
void MockTSFBridge::OnTextLayoutChanged() {
++on_text_layout_changed_;
}
void MockTSFBridge::SetFocusedClient(HWND focused_window, void MockTSFBridge::SetFocusedClient(HWND focused_window,
TextInputClient* client) { TextInputClient* client) {
++set_focused_client_call_count_; ++set_focused_client_call_count_;
...@@ -69,7 +65,6 @@ void MockTSFBridge::Reset() { ...@@ -69,7 +65,6 @@ void MockTSFBridge::Reset() {
enable_ime_call_count_ = 0; enable_ime_call_count_ = 0;
disalbe_ime_call_count_ = 0; disalbe_ime_call_count_ = 0;
cancel_composition_call_count_ = 0; cancel_composition_call_count_ = 0;
on_text_layout_changed_ = 0;
associate_focus_call_count_ = 0; associate_focus_call_count_ = 0;
set_focused_client_call_count_ = 0; set_focused_client_call_count_ = 0;
remove_focused_client_call_count_ = 0; remove_focused_client_call_count_ = 0;
......
...@@ -23,7 +23,6 @@ class MockTSFBridge : public TSFBridge { ...@@ -23,7 +23,6 @@ class MockTSFBridge : public TSFBridge {
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
virtual bool CancelComposition() OVERRIDE; virtual bool CancelComposition() OVERRIDE;
virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE; virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE;
virtual void OnTextLayoutChanged() OVERRIDE;
virtual void SetFocusedClient(HWND focused_window, virtual void SetFocusedClient(HWND focused_window,
TextInputClient* client) OVERRIDE; TextInputClient* client) OVERRIDE;
virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE; virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE;
...@@ -47,11 +46,6 @@ class MockTSFBridge : public TSFBridge { ...@@ -47,11 +46,6 @@ class MockTSFBridge : public TSFBridge {
return cancel_composition_call_count_; return cancel_composition_call_count_;
} }
// Call count of OnTextLayoutChanged().
int on_text_layout_changed() const {
return on_text_layout_changed_;
}
// Call count of AssociateFocus(). // Call count of AssociateFocus().
int associate_focus_call_count() const { return associate_focus_call_count_; } int associate_focus_call_count() const { return associate_focus_call_count_; }
...@@ -81,7 +75,6 @@ class MockTSFBridge : public TSFBridge { ...@@ -81,7 +75,6 @@ class MockTSFBridge : public TSFBridge {
int enable_ime_call_count_; int enable_ime_call_count_;
int disalbe_ime_call_count_; int disalbe_ime_call_count_;
int cancel_composition_call_count_; int cancel_composition_call_count_;
int on_text_layout_changed_;
int associate_focus_call_count_; int associate_focus_call_count_;
int set_focused_client_call_count_; int set_focused_client_call_count_;
int remove_focused_client_call_count_; int remove_focused_client_call_count_;
......
...@@ -39,7 +39,6 @@ class TSFBridgeDelegate : public TSFBridge { ...@@ -39,7 +39,6 @@ class TSFBridgeDelegate : public TSFBridge {
// TsfBridge: // TsfBridge:
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE; virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE;
virtual void OnTextLayoutChanged() OVERRIDE;
virtual bool CancelComposition() OVERRIDE; virtual bool CancelComposition() OVERRIDE;
virtual void SetFocusedClient(HWND focused_window, virtual void SetFocusedClient(HWND focused_window,
TextInputClient* client) OVERRIDE; TextInputClient* client) OVERRIDE;
...@@ -75,6 +74,13 @@ class TSFBridgeDelegate : public TSFBridge { ...@@ -75,6 +74,13 @@ class TSFBridgeDelegate : public TSFBridge {
// Returns true if already initialized. // Returns true if already initialized.
bool IsInitialized(); bool IsInitialized();
// Returns an instance of ITfDocumentMgr that is associated with the
// current TextInputType of |client_|.
base::win::ScopedComPtr<ITfDocumentMgr> GetAssociatedDocumentManager();
// An ITfThreadMgr object to be used in focus and document management.
base::win::ScopedComPtr<ITfThreadMgr> thread_manager_;
// A triple of document manager, text store and binding cookie between // A triple of document manager, text store and binding cookie between
// a context owned by the document manager and the text store. This is a // a context owned by the document manager and the text store. This is a
// minimum working set of an editable document in TSF. // minimum working set of an editable document in TSF.
...@@ -89,17 +95,10 @@ class TSFBridgeDelegate : public TSFBridge { ...@@ -89,17 +95,10 @@ class TSFBridgeDelegate : public TSFBridge {
DWORD cookie; DWORD cookie;
}; };
// Returns a pointer to TSFDocument that is associated with the current
// TextInputType of |client_|.
TSFDocument* GetAssociatedDocument();
// An ITfThreadMgr object to be used in focus and document management.
base::win::ScopedComPtr<ITfThreadMgr> thread_manager_;
// A map from TextInputType to an editable document for TSF. We use multiple // A map from TextInputType to an editable document for TSF. We use multiple
// TSF documents that have different InputScopes and TSF attributes based on // TSF documents that have different InputScopes and TSF attributes based on
// the TextInputType associated with the target document. For a TextInputType // the TextInputType associated with the target document. For a TextInputType
// that is not converted by this map, a default document, e.g. the document // that is not coverted by this map, a default document, e.g. the document
// for TEXT_INPUT_TYPE_TEXT, should be used. // for TEXT_INPUT_TYPE_TEXT, should be used.
// Note that some IMEs don't change their state unless the document focus is // Note that some IMEs don't change their state unless the document focus is
// changed. This is why we use multiple documents instead of changing TSF // changed. This is why we use multiple documents instead of changing TSF
...@@ -199,20 +198,8 @@ void TSFBridgeDelegate::OnTextInputTypeChanged(TextInputClient* client) { ...@@ -199,20 +198,8 @@ void TSFBridgeDelegate::OnTextInputTypeChanged(TextInputClient* client) {
// Called from not focusing client. Do nothing. // Called from not focusing client. Do nothing.
return; return;
} }
TSFDocument* document = GetAssociatedDocument();
if (!document)
return;
thread_manager_->SetFocus(document->document_manager.get());
OnTextLayoutChanged();
}
void TSFBridgeDelegate::OnTextLayoutChanged() { thread_manager_->SetFocus(GetAssociatedDocumentManager().get());
TSFDocument* document = GetAssociatedDocument();
if (!document)
return;
if (!document->text_store)
return;
document->text_store->SendOnLayoutChange();
} }
bool TSFBridgeDelegate::CancelComposition() { bool TSFBridgeDelegate::CancelComposition() {
...@@ -430,14 +417,13 @@ bool TSFBridgeDelegate::IsInitialized() { ...@@ -430,14 +417,13 @@ bool TSFBridgeDelegate::IsInitialized() {
return client_id_ != TF_CLIENTID_NULL; return client_id_ != TF_CLIENTID_NULL;
} }
TSFBridgeDelegate::TSFDocument* TSFBridgeDelegate::GetAssociatedDocument() { base::win::ScopedComPtr<ITfDocumentMgr>
if (!client_) TSFBridgeDelegate::GetAssociatedDocumentManager() {
return NULL; TSFDocumentMap::const_iterator it =
TSFDocumentMap::iterator it =
tsf_document_map_.find(client_->GetTextInputType()); tsf_document_map_.find(client_->GetTextInputType());
if (it == tsf_document_map_.end()) if (it == tsf_document_map_.end())
return &tsf_document_map_[TEXT_INPUT_TYPE_TEXT]; return tsf_document_map_[TEXT_INPUT_TYPE_TEXT].document_manager;
return &it->second; return it->second.document_manager;
} }
} // namespace } // namespace
......
...@@ -51,11 +51,8 @@ class UI_EXPORT TSFBridge { ...@@ -51,11 +51,8 @@ class UI_EXPORT TSFBridge {
// unless |client| is focused. // unless |client| is focused.
virtual void OnTextInputTypeChanged(TextInputClient* client) = 0; virtual void OnTextInputTypeChanged(TextInputClient* client) = 0;
// Sends an event to TSF manager that the text layout should be updated.
virtual void OnTextLayoutChanged() = 0;
// Cancels the ongoing composition if exists. // Cancels the ongoing composition if exists.
// Returns false if an error occurs. // Returns false if an error occures.
virtual bool CancelComposition() = 0; virtual bool CancelComposition() = 0;
// Sets currently focused TextInputClient. // Sets currently focused TextInputClient.
......
...@@ -7,17 +7,14 @@ ...@@ -7,17 +7,14 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/win/metro.h"
#include "ui/base/events/event.h" #include "ui/base/events/event.h"
#include "ui/base/events/event_constants.h" #include "ui/base/events/event_constants.h"
#include "ui/base/events/event_utils.h" #include "ui/base/events/event_utils.h"
#include "ui/base/ime/composition_text.h" #include "ui/base/ime/composition_text.h"
#include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h" #include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/win/tsf_bridge.h"
#include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/keycodes/keyboard_codes.h"
#include "ui/base/win/hwnd_util.h" #include "ui/base/win/hwnd_util.h"
#include "ui/views/win/hwnd_util.h"
// Extra number of chars before and after selection (or composition) range which // Extra number of chars before and after selection (or composition) range which
// is returned to IME for improving conversion accuracy. // is returned to IME for improving conversion accuracy.
...@@ -49,32 +46,11 @@ void InputMethodWin::Init(Widget* widget) { ...@@ -49,32 +46,11 @@ void InputMethodWin::Init(Widget* widget) {
} }
void InputMethodWin::OnFocus() { void InputMethodWin::OnFocus() {
if (base::win::IsTSFAwareRequired()) { UpdateIMEState();
if (GetTextInputClient()) {
ui::TSFBridge* tsf_bridge = ui::TSFBridge::GetInstance();
tsf_bridge->SetFocusedClient(hwnd_, GetTextInputClient());
}
} else {
// Use switch here in case we are going to add more text input types.
// We disable input method in password field.
switch (GetTextInputType()) {
case ui::TEXT_INPUT_TYPE_NONE:
case ui::TEXT_INPUT_TYPE_PASSWORD:
ime_input_.DisableIME(hwnd_);
break;
default:
ime_input_.EnableIME(hwnd_);
break;
}
OnTextInputTypeChanged(GetFocusedView());
OnCaretBoundsChanged(GetFocusedView());
}
} }
void InputMethodWin::OnBlur() { void InputMethodWin::OnBlur() {
ConfirmCompositionText(); ConfirmCompositionText();
if (base::win::IsTSFAwareRequired() && GetTextInputClient())
ui::TSFBridge::GetInstance()->RemoveFocusedClient(GetTextInputClient());
} }
void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) { void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) {
...@@ -103,49 +79,22 @@ void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) { ...@@ -103,49 +79,22 @@ void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) {
void InputMethodWin::OnTextInputTypeChanged(View* view) { void InputMethodWin::OnTextInputTypeChanged(View* view) {
if (IsViewFocused(view)) { if (IsViewFocused(view)) {
if (base::win::IsTSFAwareRequired()) {
if (GetTextInputClient()) {
ui::TSFBridge::GetInstance()->OnTextInputTypeChanged(
GetTextInputClient());
}
} else {
ime_input_.CancelIME(hwnd_); ime_input_.CancelIME(hwnd_);
// Use switch here in case we are going to add more text input types. UpdateIMEState();
// We disable input method in password field.
switch (GetTextInputType()) {
case ui::TEXT_INPUT_TYPE_NONE:
case ui::TEXT_INPUT_TYPE_PASSWORD:
ime_input_.DisableIME(hwnd_);
break;
default:
ime_input_.EnableIME(hwnd_);
break;
}
OnCaretBoundsChanged(GetFocusedView());
}
} }
InputMethodBase::OnTextInputTypeChanged(view); InputMethodBase::OnTextInputTypeChanged(view);
} }
void InputMethodWin::OnCaretBoundsChanged(View* view) { void InputMethodWin::OnCaretBoundsChanged(View* view) {
if (base::win::IsTSFAwareRequired()) {
ui::TSFBridge::GetInstance()->OnTextLayoutChanged();
} else {
gfx::Rect rect; gfx::Rect rect;
if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect)) if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
return; return;
ime_input_.UpdateCaretRect(hwnd_, rect); ime_input_.UpdateCaretRect(hwnd_, rect);
}
} }
void InputMethodWin::CancelComposition(View* view) { void InputMethodWin::CancelComposition(View* view) {
if (IsViewFocused(view)) { if (IsViewFocused(view))
if (base::win::IsTSFAwareRequired()) {
ui::TSFBridge::GetInstance()->CancelComposition();
} else {
ime_input_.CancelIME(hwnd_); ime_input_.CancelIME(hwnd_);
}
}
} }
std::string InputMethodWin::GetInputLocale() { std::string InputMethodWin::GetInputLocale() {
...@@ -207,26 +156,7 @@ void InputMethodWin::OnWillChangeFocus(View* focused_before, View* focused) { ...@@ -207,26 +156,7 @@ void InputMethodWin::OnWillChangeFocus(View* focused_before, View* focused) {
} }
void InputMethodWin::OnDidChangeFocus(View* focused_before, View* focused) { void InputMethodWin::OnDidChangeFocus(View* focused_before, View* focused) {
if (base::win::IsTSFAwareRequired()) { UpdateIMEState();
if (GetTextInputClient()) {
ui::TSFBridge::GetInstance()->SetFocusedClient(HWNDForView(focused),
GetTextInputClient());
}
} else {
// Use switch here in case we are going to add more text input types.
// We disable input method in password field.
switch (GetTextInputType()) {
case ui::TEXT_INPUT_TYPE_NONE:
case ui::TEXT_INPUT_TYPE_PASSWORD:
ime_input_.DisableIME(hwnd_);
break;
default:
ime_input_.EnableIME(hwnd_);
break;
}
OnTextInputTypeChanged(GetFocusedView());
OnCaretBoundsChanged(GetFocusedView());
}
} }
void InputMethodWin::OnInputLangChange(DWORD character_set, void InputMethodWin::OnInputLangChange(DWORD character_set,
...@@ -349,7 +279,7 @@ LRESULT InputMethodWin::OnChar( ...@@ -349,7 +279,7 @@ LRESULT InputMethodWin::OnChar(
// Explicitly show the system menu at a good location on [Alt]+[Space]. // Explicitly show the system menu at a good location on [Alt]+[Space].
// Note: Setting |handled| to FALSE for DefWindowProc triggering of the system // Note: Setting |handled| to FALSE for DefWindowProc triggering of the system
// menu causes undesirable titlebar artifacts in the classic theme. // menu causes unsdesirable titlebar artifacts in the classic theme.
if (message == WM_SYSCHAR && wparam == VK_SPACE) if (message == WM_SYSCHAR && wparam == VK_SPACE)
ui::ShowSystemMenu(hwnd_); ui::ShowSystemMenu(hwnd_);
...@@ -434,7 +364,7 @@ LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING* reconv) { ...@@ -434,7 +364,7 @@ LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING* reconv) {
memcpy((char*)reconv + sizeof(RECONVERTSTRING), memcpy((char*)reconv + sizeof(RECONVERTSTRING),
text.c_str(), len * sizeof(WCHAR)); text.c_str(), len * sizeof(WCHAR));
// According to Microsoft API document, IMR_RECONVERTSTRING and // According to Microsft API document, IMR_RECONVERTSTRING and
// IMR_DOCUMENTFEED should return reconv, but some applications return // IMR_DOCUMENTFEED should return reconv, but some applications return
// need_size. // need_size.
return reinterpret_cast<LRESULT>(reconv); return reinterpret_cast<LRESULT>(reconv);
...@@ -517,20 +447,26 @@ LRESULT InputMethodWin::OnQueryCharPosition(IMECHARPOSITION *char_positon) { ...@@ -517,20 +447,26 @@ LRESULT InputMethodWin::OnQueryCharPosition(IMECHARPOSITION *char_positon) {
void InputMethodWin::ConfirmCompositionText() { void InputMethodWin::ConfirmCompositionText() {
if (!IsTextInputTypeNone()) { if (!IsTextInputTypeNone()) {
if (base::win::IsTSFAwareRequired()) {
// TSFBridge has not implemented ConfirmComposition yet. So here cancel
// the composition instead as a workaround.
// TODO(ime): Implement ConfirmComposition for TSF.
ui::TSFBridge::GetInstance()->CancelComposition();
} else {
ime_input_.CleanupComposition(hwnd_); ime_input_.CleanupComposition(hwnd_);
// Though above line should confirm the client's composition text by // Though above line should confirm the client's composition text by sending
// sending a result text to us, in case the input method and the client // a result text to us, in case the input method and the client are in
// are in inconsistent states, we check the client's composition state // inconsistent states, we check the client's composition state again.
// again.
if (GetTextInputClient()->HasCompositionText()) if (GetTextInputClient()->HasCompositionText())
GetTextInputClient()->ConfirmCompositionText(); GetTextInputClient()->ConfirmCompositionText();
} }
}
void InputMethodWin::UpdateIMEState() {
// Use switch here in case we are going to add more text input types.
// We disable input method in password field.
switch (GetTextInputType()) {
case ui::TEXT_INPUT_TYPE_NONE:
case ui::TEXT_INPUT_TYPE_PASSWORD:
ime_input_.DisableIME(hwnd_);
break;
default:
ime_input_.EnableIME(hwnd_);
break;
} }
} }
......
...@@ -82,6 +82,9 @@ class InputMethodWin : public InputMethodBase { ...@@ -82,6 +82,9 @@ class InputMethodWin : public InputMethodBase {
// Asks the client to confirm current composition text. // Asks the client to confirm current composition text.
void ConfirmCompositionText(); void ConfirmCompositionText();
// Enables or disables the IME according to the current text input type.
void UpdateIMEState();
// The HWND this InputMethod is bound to. // The HWND this InputMethod is bound to.
HWND hwnd_; HWND hwnd_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment