Chromium Code Reviews| Index: chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| index 12afb42ee61cf6379b7c3b9cb0e160920835e206..f998eb07450780f41cc6dac518fc527d8c9cf612 100644 |
| --- a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| +++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| @@ -13,6 +13,7 @@ |
| #include "base/auto_reset.h" |
| #include "base/basictypes.h" |
| +#include "base/bind.h" |
| #include "base/i18n/rtl.h" |
| #include "base/lazy_instance.h" |
| #include "base/memory/ref_counted.h" |
| @@ -53,6 +54,8 @@ |
| #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
| #include "ui/base/events/event.h" |
| #include "ui/base/events/event_constants.h" |
| +#include "ui/base/ime/win/tsf_bridge.h" |
| +#include "ui/base/ime/win/tsf_event_router.h" |
| #include "ui/base/keycodes/keyboard_codes.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/l10n/l10n_util_win.h" |
| @@ -477,7 +480,8 @@ OmniboxViewWin::OmniboxViewWin(OmniboxEditController* controller, |
| chrome::search::IsInstantExtendedAPIEnabled(parent_view_->profile()), |
| ToolbarModel::NONE, LocationBarView::BACKGROUND))), |
| security_level_(ToolbarModel::NONE), |
| - text_object_model_(NULL) { |
| + text_object_model_(NULL), |
| + weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| if (!loaded_library_module_) |
| loaded_library_module_ = LoadLibrary(kRichEditDLLName); |
| @@ -538,6 +542,17 @@ OmniboxViewWin::OmniboxViewWin(OmniboxEditController* controller, |
| // the edit control will invoke RevokeDragDrop when it's being destroyed, so |
| // we don't have to do so. |
| scoped_refptr<EditDropTarget> drop_target(new EditDropTarget(this)); |
| + |
| + if (base::win::IsTsfAwareRequired()) { |
| + // Register TsfEventRouter to catch TSF related event. |
| + tsf_event_router_ = ui::TsfEventRouter::Create(); |
| + tsf_event_router_->SetTextUpdatedCallback( |
| + base::Bind(&OmniboxViewWin::OnTextUpdatedByTsf, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + tsf_event_router_->SetCandidateWindowStatusChangedCallback( |
| + base::Bind(&OmniboxViewWin::OnCandidateWindowCountChangedByTsf, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + } |
| } |
| } |
| @@ -913,6 +928,32 @@ bool OmniboxViewWin::OnAfterPossibleChangeInternal(bool force_text_changed) { |
| return something_changed; |
| } |
| +void OmniboxViewWin::OnTextUpdatedByTsf() { |
| + if (ignore_ime_messages_) |
| + return; |
| + OnAfterPossibleChangeInternal(true); |
| + // Call OnBeforePossibleChange function here to get correct diff in next IME |
| + // update. The Text Services Framework does not provide any notification |
| + // before entering edit session, therefore we don't have good place to call |
| + // OnbeforePossibleChange. |
|
falken
2012/10/18 02:15:54
nit: "OnBeforePossibleChange"
Seigo Nonaka
2012/10/18 10:02:23
Done.
|
| + OnBeforePossibleChange(); |
| +} |
| + |
| +void OmniboxViewWin::OnCandidateWindowCountChangedByTsf(size_t window_count) { |
| + ime_candidate_window_open_ = (window_count != 0); |
| + if (ime_candidate_window_open_) { |
| + CloseOmniboxPopup(); |
| + } else { |
| + // UpdatePopup assumes user input is in progress, so only call it if |
| + // that's the case. Otherwise, autocomplete may run on an empty user |
| + // text. For example, Baidu Japanese IME sends IMN_CLOSECANDIDATE when |
|
falken
2012/10/18 02:15:54
In TSF you don't get IMN_CLOSECANDIDATE messages,
Seigo Nonaka
2012/10/18 10:02:23
Done.
|
| + // composition mode is entered, but the user may not have input anything |
| + // yet. |
| + if (model()->user_input_in_progress()) |
| + UpdatePopup(); |
| + } |
| +} |
| + |
| gfx::NativeView OmniboxViewWin::GetNativeView() const { |
| return m_hWnd; |
| } |
| @@ -948,13 +989,17 @@ string16 OmniboxViewWin::GetInstantSuggestion() const { |
| } |
| bool OmniboxViewWin::IsImeComposing() const { |
| - bool ime_composing = false; |
| - HIMC context = ImmGetContext(m_hWnd); |
| - if (context) { |
| - ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); |
| - ImmReleaseContext(m_hWnd, context); |
| + if (base::win::IsTsfAwareRequired()) { |
| + return tsf_event_router_->IsImeComposing(); |
| + } else { |
| + bool ime_composing = false; |
| + HIMC context = ImmGetContext(m_hWnd); |
| + if (context) { |
| + ime_composing = !!ImmGetCompositionString(context, GCS_COMPSTR, NULL, 0); |
| + ImmReleaseContext(m_hWnd, context); |
| + } |
| + return ime_composing; |
| } |
| - return ime_composing; |
| } |
| int OmniboxViewWin::GetMaxEditWidth(int entry_width) const { |
| @@ -1582,6 +1627,9 @@ void OmniboxViewWin::OnKillFocus(HWND focus_wnd) { |
| // view, we work around this CRichEditCtrl bug. |
| SelectAll(true); |
| PlaceCaretAt(0); |
| + |
| + if (base::win::IsTsfAwareRequired()) |
| + tsf_event_router_->SetManager(NULL); |
| } |
| void OmniboxViewWin::OnLButtonDblClk(UINT keys, const CPoint& point) { |
| @@ -1909,7 +1957,16 @@ void OmniboxViewWin::OnSetFocus(HWND focus_wnd) { |
| saved_selection_for_focus_change_.cpMin = -1; |
| } |
| - SetMsgHandled(false); |
| + if (!base::win::IsTsfAwareRequired()) { |
| + SetMsgHandled(false); |
| + } else { |
| + DefWindowProc(); |
| + // Document manager created by RichEdit can be obtained only after |
| + // WM_SETFOCUS event is handled. |
| + tsf_event_router_->SetManager( |
| + ui::TsfBridge::GetInstance()->GetThreadManager()); |
| + SetMsgHandled(true); |
| + } |
| } |
| LRESULT OmniboxViewWin::OnSetText(const wchar_t* text) { |