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) {
latest_text_input_type_ = client->GetTextInputType();
}
void MockTSFBridge::OnTextLayoutChanged() {
++on_text_layout_changed_;
}
void MockTSFBridge::SetFocusedClient(HWND focused_window,
TextInputClient* client) {
++set_focused_client_call_count_;
......@@ -69,7 +65,6 @@ void MockTSFBridge::Reset() {
enable_ime_call_count_ = 0;
disalbe_ime_call_count_ = 0;
cancel_composition_call_count_ = 0;
on_text_layout_changed_ = 0;
associate_focus_call_count_ = 0;
set_focused_client_call_count_ = 0;
remove_focused_client_call_count_ = 0;
......
......@@ -23,7 +23,6 @@ class MockTSFBridge : public TSFBridge {
virtual void Shutdown() OVERRIDE;
virtual bool CancelComposition() OVERRIDE;
virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE;
virtual void OnTextLayoutChanged() OVERRIDE;
virtual void SetFocusedClient(HWND focused_window,
TextInputClient* client) OVERRIDE;
virtual void RemoveFocusedClient(TextInputClient* client) OVERRIDE;
......@@ -47,11 +46,6 @@ class MockTSFBridge : public TSFBridge {
return cancel_composition_call_count_;
}
// Call count of OnTextLayoutChanged().
int on_text_layout_changed() const {
return on_text_layout_changed_;
}
// Call count of AssociateFocus().
int associate_focus_call_count() const { return associate_focus_call_count_; }
......@@ -81,7 +75,6 @@ class MockTSFBridge : public TSFBridge {
int enable_ime_call_count_;
int disalbe_ime_call_count_;
int cancel_composition_call_count_;
int on_text_layout_changed_;
int associate_focus_call_count_;
int set_focused_client_call_count_;
int remove_focused_client_call_count_;
......
......@@ -39,7 +39,6 @@ class TSFBridgeDelegate : public TSFBridge {
// TsfBridge:
virtual void Shutdown() OVERRIDE;
virtual void OnTextInputTypeChanged(TextInputClient* client) OVERRIDE;
virtual void OnTextLayoutChanged() OVERRIDE;
virtual bool CancelComposition() OVERRIDE;
virtual void SetFocusedClient(HWND focused_window,
TextInputClient* client) OVERRIDE;
......@@ -75,6 +74,13 @@ class TSFBridgeDelegate : public TSFBridge {
// Returns true if already initialized.
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 context owned by the document manager and the text store. This is a
// minimum working set of an editable document in TSF.
......@@ -89,17 +95,10 @@ class TSFBridgeDelegate : public TSFBridge {
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
// TSF documents that have different InputScopes and TSF attributes based on
// 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.
// 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
......@@ -199,20 +198,8 @@ void TSFBridgeDelegate::OnTextInputTypeChanged(TextInputClient* client) {
// Called from not focusing client. Do nothing.
return;
}
TSFDocument* document = GetAssociatedDocument();
if (!document)
return;
thread_manager_->SetFocus(document->document_manager.get());
OnTextLayoutChanged();
}
void TSFBridgeDelegate::OnTextLayoutChanged() {
TSFDocument* document = GetAssociatedDocument();
if (!document)
return;
if (!document->text_store)
return;
document->text_store->SendOnLayoutChange();
thread_manager_->SetFocus(GetAssociatedDocumentManager().get());
}
bool TSFBridgeDelegate::CancelComposition() {
......@@ -430,14 +417,13 @@ bool TSFBridgeDelegate::IsInitialized() {
return client_id_ != TF_CLIENTID_NULL;
}
TSFBridgeDelegate::TSFDocument* TSFBridgeDelegate::GetAssociatedDocument() {
if (!client_)
return NULL;
TSFDocumentMap::iterator it =
base::win::ScopedComPtr<ITfDocumentMgr>
TSFBridgeDelegate::GetAssociatedDocumentManager() {
TSFDocumentMap::const_iterator it =
tsf_document_map_.find(client_->GetTextInputType());
if (it == tsf_document_map_.end())
return &tsf_document_map_[TEXT_INPUT_TYPE_TEXT];
return &it->second;
return tsf_document_map_[TEXT_INPUT_TYPE_TEXT].document_manager;
return it->second.document_manager;
}
} // namespace
......
......@@ -51,11 +51,8 @@ class UI_EXPORT TSFBridge {
// unless |client| is focused.
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.
// Returns false if an error occurs.
// Returns false if an error occures.
virtual bool CancelComposition() = 0;
// Sets currently focused TextInputClient.
......
......@@ -7,17 +7,14 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/win/metro.h"
#include "ui/base/events/event.h"
#include "ui/base/events/event_constants.h"
#include "ui/base/events/event_utils.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/input_method.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/win/hwnd_util.h"
#include "ui/views/win/hwnd_util.h"
// Extra number of chars before and after selection (or composition) range which
// is returned to IME for improving conversion accuracy.
......@@ -49,32 +46,11 @@ void InputMethodWin::Init(Widget* widget) {
}
void InputMethodWin::OnFocus() {
if (base::win::IsTSFAwareRequired()) {
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());
}
UpdateIMEState();
}
void InputMethodWin::OnBlur() {
ConfirmCompositionText();
if (base::win::IsTSFAwareRequired() && GetTextInputClient())
ui::TSFBridge::GetInstance()->RemoveFocusedClient(GetTextInputClient());
}
void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) {
......@@ -103,49 +79,22 @@ void InputMethodWin::DispatchKeyEvent(const ui::KeyEvent& key) {
void InputMethodWin::OnTextInputTypeChanged(View* view) {
if (IsViewFocused(view)) {
if (base::win::IsTSFAwareRequired()) {
if (GetTextInputClient()) {
ui::TSFBridge::GetInstance()->OnTextInputTypeChanged(
GetTextInputClient());
}
} else {
ime_input_.CancelIME(hwnd_);
// 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;
}
OnCaretBoundsChanged(GetFocusedView());
}
ime_input_.CancelIME(hwnd_);
UpdateIMEState();
}
InputMethodBase::OnTextInputTypeChanged(view);
}
void InputMethodWin::OnCaretBoundsChanged(View* view) {
if (base::win::IsTSFAwareRequired()) {
ui::TSFBridge::GetInstance()->OnTextLayoutChanged();
} else {
gfx::Rect rect;
if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
return;
ime_input_.UpdateCaretRect(hwnd_, rect);
}
gfx::Rect rect;
if (!IsViewFocused(view) || !GetCaretBoundsInWidget(&rect))
return;
ime_input_.UpdateCaretRect(hwnd_, rect);
}
void InputMethodWin::CancelComposition(View* view) {
if (IsViewFocused(view)) {
if (base::win::IsTSFAwareRequired()) {
ui::TSFBridge::GetInstance()->CancelComposition();
} else {
ime_input_.CancelIME(hwnd_);
}
}
if (IsViewFocused(view))
ime_input_.CancelIME(hwnd_);
}
std::string InputMethodWin::GetInputLocale() {
......@@ -207,26 +156,7 @@ void InputMethodWin::OnWillChangeFocus(View* focused_before, View* focused) {
}
void InputMethodWin::OnDidChangeFocus(View* focused_before, View* focused) {
if (base::win::IsTSFAwareRequired()) {
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());
}
UpdateIMEState();
}
void InputMethodWin::OnInputLangChange(DWORD character_set,
......@@ -349,7 +279,7 @@ LRESULT InputMethodWin::OnChar(
// Explicitly show the system menu at a good location on [Alt]+[Space].
// 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)
ui::ShowSystemMenu(hwnd_);
......@@ -434,7 +364,7 @@ LRESULT InputMethodWin::OnDocumentFeed(RECONVERTSTRING* reconv) {
memcpy((char*)reconv + sizeof(RECONVERTSTRING),
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
// need_size.
return reinterpret_cast<LRESULT>(reconv);
......@@ -517,20 +447,26 @@ LRESULT InputMethodWin::OnQueryCharPosition(IMECHARPOSITION *char_positon) {
void InputMethodWin::ConfirmCompositionText() {
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_);
// Though above line should confirm the client's composition text by
// sending a result text to us, in case the input method and the client
// are in inconsistent states, we check the client's composition state
// again.
if (GetTextInputClient()->HasCompositionText())
GetTextInputClient()->ConfirmCompositionText();
}
ime_input_.CleanupComposition(hwnd_);
// Though above line should confirm the client's composition text by sending
// a result text to us, in case the input method and the client are in
// inconsistent states, we check the client's composition state again.
if (GetTextInputClient()->HasCompositionText())
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 {
// Asks the client to confirm current composition text.
void ConfirmCompositionText();
// Enables or disables the IME according to the current text input type.
void UpdateIMEState();
// The HWND this InputMethod is bound to.
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