summaryrefslogtreecommitdiffstats
path: root/chrome/views/text_field.cc
diff options
context:
space:
mode:
authorhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-10 06:43:11 +0000
committerhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-10 06:43:11 +0000
commit253601010dde1eae42992519244e8b3ffe5499b7 (patch)
tree13b743c3608bb7ac69bbb5aed12ff8bc11a84a8e /chrome/views/text_field.cc
parentbda00571b1638107491ac3eea8f340f1ae625f01 (diff)
downloadchromium_src-253601010dde1eae42992519244e8b3ffe5499b7.zip
chromium_src-253601010dde1eae42992519244e8b3ffe5499b7.tar.gz
chromium_src-253601010dde1eae42992519244e8b3ffe5499b7.tar.bz2
Fixes Issue 3096 in chromium "[Find in page] responds each IME composition, making "not found" noises or jumping within the page."
This issue is caued by the TextField::Edit class which start searching a page with a string retrieved with the GetWindowText() function every time when a user presses a key. A string retrived with the GetWindowText() function contains a composition string, a string being composed by an IME. This string changes too often and users do not like to start searching a page with the string. To fix this issue, this change removes a composition string from a search string to emulate Firefox. BUG=3096 "Issue 3096: [Find in page] responds each IME composition, making "not found" noises or jumping within the page." Review URL: http://codereview.chromium.org/9634 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5096 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/views/text_field.cc')
-rw-r--r--chrome/views/text_field.cc77
1 files changed, 74 insertions, 3 deletions
diff --git a/chrome/views/text_field.cc b/chrome/views/text_field.cc
index c36fdbb..d45e875 100644
--- a/chrome/views/text_field.cc
+++ b/chrome/views/text_field.cc
@@ -67,6 +67,7 @@ class TextField::Edit
MSG_WM_CONTEXTMENU(OnContextMenu)
MSG_WM_COPY(OnCopy)
MSG_WM_CUT(OnCut)
+ MESSAGE_HANDLER_EX(WM_IME_STARTCOMPOSITION, OnImeStartComposition)
MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeComposition)
MSG_WM_KEYDOWN(OnKeyDown)
MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
@@ -112,6 +113,7 @@ class TextField::Edit
void OnContextMenu(HWND window, const CPoint& point);
void OnCopy();
void OnCut();
+ LRESULT OnImeStartComposition(UINT message, WPARAM wparam, LPARAM lparam);
LRESULT OnImeComposition(UINT message, WPARAM wparam, LPARAM lparam);
void OnKeyDown(TCHAR key, UINT repeat_count, UINT flags);
void OnLButtonDblClk(UINT keys, const CPoint& point);
@@ -187,6 +189,13 @@ class TextField::Edit
// This interface is useful for accessing the CRichEditCtrl at a low level.
mutable CComQIPtr<ITextDocument> text_object_model_;
+ // The position and the length of the ongoing composition string.
+ // These values are used for removing a composition string from a search
+ // text to emulate Firefox.
+ bool ime_discard_composition_;
+ int ime_composition_start_;
+ int ime_composition_length_;
+
DISALLOW_EVIL_CONSTRUCTORS(Edit);
};
@@ -230,7 +239,10 @@ TextField::Edit::Edit(TextField* parent, bool draw_border)
double_click_time_(0),
can_discard_mousemove_(false),
contains_mouse_(false),
- draw_border_(draw_border) {
+ draw_border_(draw_border),
+ ime_discard_composition_(false),
+ ime_composition_start_(0),
+ ime_composition_length_(0) {
if (!did_load_library_)
did_load_library_ = !!LoadLibrary(L"riched20.dll");
@@ -388,11 +400,53 @@ void TextField::Edit::OnCut() {
ReplaceSel(L"", true);
}
+LRESULT TextField::Edit::OnImeStartComposition(UINT message,
+ WPARAM wparam,
+ LPARAM lparam) {
+ // Users may press alt+shift or control+shift keys to change their keyboard
+ // layouts. So, we retrieve the input locale identifier everytime we start
+ // an IME composition.
+ int language_id = PRIMARYLANGID(GetKeyboardLayout(0));
+ ime_discard_composition_ =
+ language_id == LANG_JAPANESE || language_id == LANG_CHINESE;
+ ime_composition_start_ = 0;
+ ime_composition_length_ = 0;
+
+ return DefWindowProc(message, wparam, lparam);
+}
+
LRESULT TextField::Edit::OnImeComposition(UINT message,
WPARAM wparam,
LPARAM lparam) {
- OnBeforePossibleChange();
+ text_before_change_.clear();
LRESULT result = DefWindowProc(message, wparam, lparam);
+
+ ime_composition_start_ = 0;
+ ime_composition_length_ = 0;
+ if (ime_discard_composition_) {
+ // Call IMM32 functions to retrieve the position and the length of the
+ // ongoing composition string and notify the OnAfterPossibleChange()
+ // function that it should discard the composition string from a search
+ // string. We should not call IMM32 functions in the function because it
+ // is called when an IME is not composing a string.
+ HIMC imm_context = ImmGetContext(m_hWnd);
+ if (imm_context) {
+ CHARRANGE selection;
+ GetSel(selection);
+ const int cursor_position =
+ ImmGetCompositionString(imm_context, GCS_CURSORPOS, NULL, 0);
+ if (cursor_position >= 0)
+ ime_composition_start_ = selection.cpMin - cursor_position;
+
+ const int composition_size =
+ ImmGetCompositionString(imm_context, GCS_COMPSTR, NULL, 0);
+ if (composition_size >= 0)
+ ime_composition_length_ = composition_size / sizeof(wchar_t);
+
+ ImmReleaseContext(m_hWnd, imm_context);
+ }
+ }
+
OnAfterPossibleChange();
return result;
}
@@ -463,6 +517,12 @@ void TextField::Edit::OnKeyDown(TCHAR key, UINT repeat_count, UINT flags) {
case 0xbb: // Ctrl-'='. Triggers subscripting, even in plain text mode.
return;
+
+ case VK_PROCESSKEY:
+ // This key event is consumed by an IME.
+ // We ignore this event because an IME sends WM_IME_COMPOSITION messages
+ // when it updates the CRichEditCtrl text.
+ return;
}
// CRichEditCtrl changes its text on WM_KEYDOWN instead of WM_CHAR for many
@@ -715,8 +775,19 @@ void TextField::Edit::OnAfterPossibleChange() {
SetSel(new_sel);
}
- const std::wstring new_text(GetText());
+ std::wstring new_text(GetText());
if (new_text != text_before_change_) {
+ if (ime_discard_composition_ && ime_composition_start_ >= 0 &&
+ ime_composition_length_ > 0) {
+ // A string retrieved with a GetText() call contains a string being
+ // composed by an IME. We remove the composition string from this search
+ // string.
+ new_text.erase(ime_composition_start_, ime_composition_length_);
+ ime_composition_start_ = 0;
+ ime_composition_length_ = 0;
+ if (new_text.empty())
+ return;
+ }
parent_->SyncText();
if (parent_->GetController())
parent_->GetController()->ContentsChanged(parent_, new_text);