OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" |
6 | 6 |
7 #include <locale> | 7 #include <locale> |
8 | 8 |
9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 controller_(controller), | 410 controller_(controller), |
411 parent_view_(parent_view), | 411 parent_view_(parent_view), |
412 toolbar_model_(toolbar_model), | 412 toolbar_model_(toolbar_model), |
413 command_updater_(command_updater), | 413 command_updater_(command_updater), |
414 popup_window_mode_(popup_window_mode), | 414 popup_window_mode_(popup_window_mode), |
415 force_hidden_(false), | 415 force_hidden_(false), |
416 tracking_click_(false), | 416 tracking_click_(false), |
417 tracking_double_click_(false), | 417 tracking_double_click_(false), |
418 double_click_time_(0), | 418 double_click_time_(0), |
419 can_discard_mousemove_(false), | 419 can_discard_mousemove_(false), |
| 420 ignore_ime_messages_(false), |
420 font_(font), | 421 font_(font), |
421 possible_drag_(false), | 422 possible_drag_(false), |
422 in_drag_(false), | 423 in_drag_(false), |
423 initiated_drag_(false), | 424 initiated_drag_(false), |
424 drop_highlight_position_(-1), | 425 drop_highlight_position_(-1), |
425 background_color_(0), | 426 background_color_(0), |
426 scheme_security_level_(ToolbarModel::NORMAL) { | 427 scheme_security_level_(ToolbarModel::NORMAL) { |
427 model_->set_popup_model(popup_view_->GetModel()); | 428 model_->set_popup_model(popup_view_->GetModel()); |
428 | 429 |
429 saved_selection_for_focus_change_.cpMin = -1; | 430 saved_selection_for_focus_change_.cpMin = -1; |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 size_t caret_pos) { | 628 size_t caret_pos) { |
628 HIMC imm_context = ImmGetContext(m_hWnd); | 629 HIMC imm_context = ImmGetContext(m_hWnd); |
629 if (imm_context) { | 630 if (imm_context) { |
630 // In Windows Vista, SetWindowText() automatically cancels any ongoing | 631 // In Windows Vista, SetWindowText() automatically cancels any ongoing |
631 // IME composition, and updates the text of the underlying edit control. | 632 // IME composition, and updates the text of the underlying edit control. |
632 // In Windows XP, however, SetWindowText() gets applied to the IME | 633 // In Windows XP, however, SetWindowText() gets applied to the IME |
633 // composition string if it exists, and doesn't update the underlying edit | 634 // composition string if it exists, and doesn't update the underlying edit |
634 // control. To avoid this, we force the IME to cancel any outstanding | 635 // control. To avoid this, we force the IME to cancel any outstanding |
635 // compositions here. This is harmless in Vista and in cases where the IME | 636 // compositions here. This is harmless in Vista and in cases where the IME |
636 // isn't composing. | 637 // isn't composing. |
| 638 |
| 639 // NOTE: We MUST ignore messages like WM_IME_COMPOSITION that may be sent as |
| 640 // a result of doing this. Until the SetWindowText() call below, the |
| 641 // underlying edit (on XP) has out-of-date text in it; for problems this can |
| 642 // cause, see OnImeComposition(). |
| 643 ignore_ime_messages_ = true; |
637 ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_CANCEL, 0); | 644 ImmNotifyIME(imm_context, NI_COMPOSITIONSTR, CPS_CANCEL, 0); |
638 ImmReleaseContext(m_hWnd, imm_context); | 645 ImmReleaseContext(m_hWnd, imm_context); |
| 646 ignore_ime_messages_ = false; |
639 } | 647 } |
640 | 648 |
641 SetWindowText(text.c_str()); | 649 SetWindowText(text.c_str()); |
642 PlaceCaretAt(caret_pos); | 650 PlaceCaretAt(caret_pos); |
643 } | 651 } |
644 | 652 |
645 void AutocompleteEditViewWin::SetForcedQuery() { | 653 void AutocompleteEditViewWin::SetForcedQuery() { |
646 const std::wstring current_text(GetText()); | 654 const std::wstring current_text(GetText()); |
647 if (current_text.empty() || (current_text[0] != '?')) | 655 if (current_text.empty() || (current_text[0] != '?')) |
648 SetUserText(L"?"); | 656 SetUserText(L"?"); |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 return LresultFromObject(IID_IAccessible, wparam, | 1226 return LresultFromObject(IID_IAccessible, wparam, |
1219 autocomplete_accessibility_.p); | 1227 autocomplete_accessibility_.p); |
1220 } | 1228 } |
1221 } | 1229 } |
1222 return 0; | 1230 return 0; |
1223 } | 1231 } |
1224 | 1232 |
1225 LRESULT AutocompleteEditViewWin::OnImeComposition(UINT message, | 1233 LRESULT AutocompleteEditViewWin::OnImeComposition(UINT message, |
1226 WPARAM wparam, | 1234 WPARAM wparam, |
1227 LPARAM lparam) { | 1235 LPARAM lparam) { |
| 1236 if (ignore_ime_messages_) { |
| 1237 // This message was sent while we're in the middle of meddling with the |
| 1238 // underlying edit control. If we handle it below, OnAfterPossibleChange() |
| 1239 // can get bogus text for the edit, and rerun autocomplete, destructively |
| 1240 // modifying the result set that we're in the midst of using. For example, |
| 1241 // if SetWindowTextAndCaretPos() was called due to the user clicking an |
| 1242 // entry in the popup, we're in the middle of executing SetSelectedLine(), |
| 1243 // and changing the results can cause checkfailures. |
| 1244 return DefWindowProc(message, wparam, lparam); |
| 1245 } |
| 1246 |
1228 ScopedFreeze freeze(this, GetTextObjectModel()); | 1247 ScopedFreeze freeze(this, GetTextObjectModel()); |
1229 OnBeforePossibleChange(); | 1248 OnBeforePossibleChange(); |
1230 LRESULT result = DefWindowProc(message, wparam, lparam); | 1249 LRESULT result = DefWindowProc(message, wparam, lparam); |
1231 if (!OnAfterPossibleChange() && (lparam & GCS_RESULTSTR)) { | 1250 if (!OnAfterPossibleChange() && (lparam & GCS_RESULTSTR)) { |
1232 // The result string changed, but the text in the popup didn't actually | 1251 // The result string changed, but the text in the popup didn't actually |
1233 // change. This means the user finalized the composition. Rerun | 1252 // change. This means the user finalized the composition. Rerun |
1234 // autocomplete so that we can now trigger inline autocomplete if | 1253 // autocomplete so that we can now trigger inline autocomplete if |
1235 // applicable. | 1254 // applicable. |
1236 // | 1255 // |
1237 // Note that if we're in the midst of losing focus, UpdatePopup() won't | 1256 // Note that if we're in the midst of losing focus, UpdatePopup() won't |
1238 // actually rerun autocomplete, but will just set local state correctly. | 1257 // actually rerun autocomplete, but will just set local state correctly. |
1239 UpdatePopup(); | 1258 UpdatePopup(); |
1240 } | 1259 } |
1241 return result; | 1260 return result; |
1242 } | 1261 } |
1243 | 1262 |
1244 LRESULT AutocompleteEditViewWin::OnImeNotify(UINT message, | 1263 LRESULT AutocompleteEditViewWin::OnImeNotify(UINT message, |
1245 WPARAM wparam, | 1264 WPARAM wparam, |
1246 LPARAM lparam) { | 1265 LPARAM lparam) { |
1247 if (wparam == IMN_SETOPENSTATUS) { | 1266 // NOTE: I'm not sure this is ever reached with |ignore_ime_messages_| set, |
| 1267 // but if it is, the safe thing to do is to only call DefWindowProc(). |
| 1268 if (!ignore_ime_messages_ && (wparam == IMN_SETOPENSTATUS)) { |
1248 // A user has activated (or deactivated) IMEs (but not started a | 1269 // A user has activated (or deactivated) IMEs (but not started a |
1249 // composition). | 1270 // composition). |
1250 // Some IMEs get confused when we accept keywords while they are composing | 1271 // Some IMEs get confused when we accept keywords while they are composing |
1251 // text. To prevent this situation, we accept keywords when an IME is | 1272 // text. To prevent this situation, we accept keywords when an IME is |
1252 // activated. | 1273 // activated. |
1253 HIMC imm_context = ImmGetContext(m_hWnd); | 1274 HIMC imm_context = ImmGetContext(m_hWnd); |
1254 if (imm_context) { | 1275 if (imm_context) { |
1255 if (ImmGetOpenStatus(imm_context) && | 1276 if (ImmGetOpenStatus(imm_context) && |
1256 model_->is_keyword_hint() && !model_->keyword().empty()) { | 1277 model_->is_keyword_hint() && !model_->keyword().empty()) { |
1257 ScopedFreeze freeze(this, GetTextObjectModel()); | 1278 ScopedFreeze freeze(this, GetTextObjectModel()); |
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2342 context_menu_contents_->AddItemWithStringId(IDS_PASTE_AND_GO, | 2363 context_menu_contents_->AddItemWithStringId(IDS_PASTE_AND_GO, |
2343 IDS_PASTE_AND_GO); | 2364 IDS_PASTE_AND_GO); |
2344 context_menu_contents_->AddSeparator(); | 2365 context_menu_contents_->AddSeparator(); |
2345 context_menu_contents_->AddItemWithStringId(IDS_SELECT_ALL, IDS_SELECT_ALL); | 2366 context_menu_contents_->AddItemWithStringId(IDS_SELECT_ALL, IDS_SELECT_ALL); |
2346 context_menu_contents_->AddSeparator(); | 2367 context_menu_contents_->AddSeparator(); |
2347 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, | 2368 context_menu_contents_->AddItemWithStringId(IDS_EDIT_SEARCH_ENGINES, |
2348 IDS_EDIT_SEARCH_ENGINES); | 2369 IDS_EDIT_SEARCH_ENGINES); |
2349 } | 2370 } |
2350 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); | 2371 context_menu_.reset(new views::Menu2(context_menu_contents_.get())); |
2351 } | 2372 } |
OLD | NEW |