Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4963)

Unified Diff: chrome/browser/ui/views/omnibox/omnibox_view_win.cc

Issue 11418144: [Search] Implementation of the invisible focus on Windows (Closed) Base URL: http://git.chromium.org/chromium/src.git@samarthlatest
Patch Set: Comments, mouse-click, SetFocus Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a0050fa91d794d110e0305870b7f1167e1dac99b 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_view_win.cc
@@ -760,11 +760,41 @@ void OmniboxViewWin::UpdatePopup() {
void OmniboxViewWin::SetFocus() {
::SetFocus(m_hWnd);
-}
-
-void OmniboxViewWin::ApplyFocusVisibility() {
- // TODO(mathp): implement for Windows.
- NOTIMPLEMENTED();
+ // Restore caret visibility if focused explicitly. We need to do this here
+ // because the ::SetFocus() call will not reach
+ // OmniboxEditModel::OnSetFocus() in cases where we already had focus, such as
+ // when a new tab is created and the previous tab had invisible focus.
Peter Kasting 2012/12/05 04:10:57 Given that this apparently does short-circuit, I t
Mathieu 2012/12/05 04:28:35 Done.
+ model()->SetCaretVisibility(true);
Peter Kasting 2012/12/05 04:10:57 The Views impl calls this before setting focus. I
Mathieu 2012/12/05 04:28:35 This is definitely the right order for Windows, si
Peter Kasting 2012/12/05 04:31:17 K. See if you can get the other CL to change to m
+}
+
+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 even hide and destroy the caret if we're going to create it again below.
+ // If the caret was already visible on entry to this function, the
+ // CreateCaret() call (which first destroys the old caret) might leave a solid
+ // vertical bar for the same reason as above. Unconditionally hiding prevents
+ // this. The caret could be visible on entry to this function if the
+ // underlying edit control had re-created it automatically (see comments in
+ // OnPaint()).
+ 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) {
@@ -1741,25 +1771,32 @@ LRESULT OmniboxViewWin::OnMouseActivate(HWND window,
// reached before OnXButtonDown(), preventing us from detecting this properly
// there. Also in those cases, we need to already know in OnSetFocus() that
// we should not restore the saved selection.
- if (!model()->has_focus() &&
- ((mouse_message == WM_LBUTTONDOWN || mouse_message == WM_RBUTTONDOWN)) &&
+ if (((mouse_message == WM_LBUTTONDOWN || mouse_message == WM_RBUTTONDOWN)) &&
(result == MA_ACTIVATE)) {
- if (gaining_focus_) {
- // On Windows 8 in metro mode, we get two WM_MOUSEACTIVATE messages when
- // we click on the omnibox with the mouse.
- DCHECK(base::win::IsMetroProcess());
- return result;
+ if (model()->has_focus()) {
Peter Kasting 2012/12/05 04:10:57 I don't understand why you did things this way ins
Mathieu 2012/12/05 04:28:35 Discussed offline. I had misunderstood the origina
+ if (!model()->is_caret_visible()) {
+ // Explicitely setting visibility of the focus as a result of directly
+ // clicking on the omnibox while it has invisible focus.
+ SetCaretVisibility(true);
+ }
+ } else {
+ if (gaining_focus_) {
+ // On Windows 8 in metro mode, we get two WM_MOUSEACTIVATE messages when
+ // we click on the omnibox with the mouse.
+ DCHECK(base::win::IsMetroProcess());
+ return result;
+ }
+ gaining_focus_.reset(new ScopedFreeze(this, GetTextObjectModel()));
+ // NOTE: Despite |mouse_message| being WM_XBUTTONDOWN here, we're not
+ // guaranteed to call OnXButtonDown() later! Specifically, if this is the
+ // second click of a double click, we'll reach here but later call
+ // OnXButtonDblClk(). Make sure |gaining_focus_| gets reset both places,
+ // or we'll have visual glitchiness and then DCHECK failures.
+
+ // Don't restore saved selection, it will just screw up our interaction
+ // with this edit.
+ saved_selection_for_focus_change_.cpMin = -1;
}
- gaining_focus_.reset(new ScopedFreeze(this, GetTextObjectModel()));
- // NOTE: Despite |mouse_message| being WM_XBUTTONDOWN here, we're not
- // guaranteed to call OnXButtonDown() later! Specifically, if this is the
- // second click of a double click, we'll reach here but later call
- // OnXButtonDblClk(). Make sure |gaining_focus_| gets reset both places,
- // or we'll have visual glitchiness and then DCHECK failures.
-
- // Don't restore saved selection, it will just screw up our interaction
- // with this edit.
- saved_selection_for_focus_change_.cpMin = -1;
}
return result;
}
@@ -1899,6 +1936,12 @@ 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). This is because the
+ // underlying edit control will automatically re-create the caret when it
+ // receives certain events that trigger repaints, e.g. window resize events.
+ ApplyCaretVisibility();
}
void OmniboxViewWin::OnPaste() {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698