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 cdfce5fc6b9f1a7eb3e29d7aae290b38491a33b1..295f44d3bb392d4bf36703557e81e8f191b83e5c 100644 |
| --- a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| +++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc |
| @@ -760,11 +760,32 @@ void OmniboxViewWin::UpdatePopup() { |
| void OmniboxViewWin::SetFocus() { |
| ::SetFocus(m_hWnd); |
| -} |
| - |
| -void OmniboxViewWin::ApplyFocusVisibility() { |
| - // TODO(mathp): implement for Windows. |
| - NOTIMPLEMENTED(); |
| + model()->SetFocusVisibility(true); |
| +} |
| + |
| +void OmniboxViewWin::ApplyCaretVisibility() { |
| + // We hide the caret just before destroying it, since destroying a caret that |
| + // is in the "solid" phase of its blinking will leave a solid vertical bar. |
| + // We also hide and destroy the caret before re-creating it, to avoid a solid |
| + // vertical bar. |
|
Peter Kasting
2012/12/04 22:45:35
Nit: This second sentence might be clearer as:
"W
Mathieu
2012/12/05 01:51:20
Done. It's precisely right and well worded.
|
| + HideCaret(); |
| + // We use DestroyCaret()/CreateCaret() instead of simply HideCaret()/ |
| + // ShowCaret() because HideCaret() is not sticky across paint events, e.g. a |
| + // window resize will effectively restore caret visibility, regardless of |
| + // whether HideCaret() was called before. While we do catch and handle these |
| + // paint events (see OnPaint()), it doesn't seem to be enough to simply call |
| + // HideCaret() while handling them because of the unpredictability of this |
| + // Windows API. According to the documentation, it should be a cumulative call |
| + // e.g. 5 hide calls should be balanced by 5 show calls. We have not found |
| + // this to be true, which may be explained by the fact that this API is called |
| + // internally in Windows, as well. |
| + ::DestroyCaret(); |
| + if (model()->is_focus_visible()) { |
| + ::CreateCaret(m_hWnd, (HBITMAP) NULL, 1, font_.GetHeight()); |
| + // According to the Windows API documentation, a newly created caret needs |
| + // ShowCaret to be visible. |
| + ShowCaret(); |
| + } |
| } |
| void OmniboxViewWin::SetDropHighlightPosition(int position) { |
| @@ -849,6 +870,10 @@ void OmniboxViewWin::OnRevertTemporaryText() { |
| } |
| void OmniboxViewWin::OnBeforePossibleChange() { |
| + // We set the focus to visible here to cover two cases. This is called when |
| + // the user directly clicks on the omnibox as well as when a character is |
| + // about to be entered. |
| + model()->SetFocusVisibility(true); |
| // Record our state. |
| text_before_change_ = GetText(); |
| GetSelection(sel_before_change_); |
| @@ -1899,6 +1924,11 @@ void OmniboxViewWin::OnPaint(HDC bogus_hdc) { |
| rect.left, rect.top, SRCCOPY); |
| memory_dc.SelectBitmap(old_bitmap); |
| edit_hwnd = old_edit_hwnd; |
| + |
| + // This needs to be called regardless of the current state of the caret, even |
| + // if reaffirming a current state (hidden or shown). Otherwise, the caret may |
| + // show when it is supposed to be hidden (i.e. it is re-created by the OS). |
|
Peter Kasting
2012/12/04 22:45:35
Nit: If you could be clearer in this second senten
Mathieu
2012/12/05 01:51:20
Done. I modified a little bit to say "paint events
|
| + ApplyCaretVisibility(); |
| } |
| void OmniboxViewWin::OnPaste() { |