diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.cc | 23 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_win.h | 4 |
2 files changed, 26 insertions, 1 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 4c75e0c..ca6040a 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -417,6 +417,7 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( tracking_double_click_(false), double_click_time_(0), can_discard_mousemove_(false), + ignore_ime_messages_(false), font_(font), possible_drag_(false), in_drag_(false), @@ -634,8 +635,15 @@ void AutocompleteEditViewWin::SetWindowTextAndCaretPos(const std::wstring& text, // control. To avoid this, we force the IME to cancel any outstanding // compositions here. This is harmless in Vista and in cases where the IME // isn't composing. + + // NOTE: We MUST ignore messages like WM_IME_COMPOSITION that may be sent as + // a result of doing this. Until the SetWindowText() call below, the + // underlying edit (on XP) has out-of-date text in it; for problems this can + // cause, see OnImeComposition(). + ignore_ime_messages_ = true; ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_CANCEL, 0); ImmReleaseContext(m_hWnd, imm_context); + ignore_ime_messages_ = false; } SetWindowText(text.c_str()); @@ -1225,6 +1233,17 @@ LRESULT AutocompleteEditViewWin::OnGetObject(UINT uMsg, LRESULT AutocompleteEditViewWin::OnImeComposition(UINT message, WPARAM wparam, LPARAM lparam) { + if (ignore_ime_messages_) { + // This message was sent while we're in the middle of meddling with the + // underlying edit control. If we handle it below, OnAfterPossibleChange() + // can get bogus text for the edit, and rerun autocomplete, destructively + // modifying the result set that we're in the midst of using. For example, + // if SetWindowTextAndCaretPos() was called due to the user clicking an + // entry in the popup, we're in the middle of executing SetSelectedLine(), + // and changing the results can cause checkfailures. + return DefWindowProc(message, wparam, lparam); + } + ScopedFreeze freeze(this, GetTextObjectModel()); OnBeforePossibleChange(); LRESULT result = DefWindowProc(message, wparam, lparam); @@ -1244,7 +1263,9 @@ LRESULT AutocompleteEditViewWin::OnImeComposition(UINT message, LRESULT AutocompleteEditViewWin::OnImeNotify(UINT message, WPARAM wparam, LPARAM lparam) { - if (wparam == IMN_SETOPENSTATUS) { + // NOTE: I'm not sure this is ever reached with |ignore_ime_messages_| set, + // but if it is, the safe thing to do is to only call DefWindowProc(). + if (!ignore_ime_messages_ && (wparam == IMN_SETOPENSTATUS)) { // A user has activated (or deactivated) IMEs (but not started a // composition). // Some IMEs get confused when we accept keywords while they are composing diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h index 0c91820..986e799 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h @@ -420,6 +420,10 @@ class AutocompleteEditViewWin // unnecessary event. See detailed comments in OnMouseMove(). bool can_discard_mousemove_; + // Used to prevent IME message handling in the midst of updating the edit + // text. See comments where this is used. + bool ignore_ime_messages_; + // Variables for tracking state before and after a possible change. std::wstring text_before_change_; CHARRANGE sel_before_change_; |