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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/ui/views/omnibox/omnibox_view_win.h" 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <locale> 8 #include <locale>
9 #include <string> 9 #include <string>
10 10
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 // * The user has just pasted in something that replaced all the text 753 // * The user has just pasted in something that replaced all the text
754 // * The user is trying to compose something in an IME 754 // * The user is trying to compose something in an IME
755 CHARRANGE sel; 755 CHARRANGE sel;
756 GetSel(sel); 756 GetSel(sel);
757 model()->StartAutocomplete(sel.cpMax != sel.cpMin, 757 model()->StartAutocomplete(sel.cpMax != sel.cpMin,
758 (sel.cpMax < GetTextLength()) || IsImeComposing()); 758 (sel.cpMax < GetTextLength()) || IsImeComposing());
759 } 759 }
760 760
761 void OmniboxViewWin::SetFocus() { 761 void OmniboxViewWin::SetFocus() {
762 ::SetFocus(m_hWnd); 762 ::SetFocus(m_hWnd);
763 // Restore caret visibility if focused explicitly. We need to do this here
764 // because the ::SetFocus() call will not reach
765 // OmniboxEditModel::OnSetFocus() in cases where we already had focus, such as
766 // 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.
767 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
763 } 768 }
764 769
765 void OmniboxViewWin::ApplyFocusVisibility() { 770 void OmniboxViewWin::ApplyCaretVisibility() {
766 // TODO(mathp): implement for Windows. 771 // We hide the caret just before destroying it, since destroying a caret that
767 NOTIMPLEMENTED(); 772 // is in the "solid" phase of its blinking will leave a solid vertical bar.
773 // We even hide and destroy the caret if we're going to create it again below.
774 // If the caret was already visible on entry to this function, the
775 // CreateCaret() call (which first destroys the old caret) might leave a solid
776 // vertical bar for the same reason as above. Unconditionally hiding prevents
777 // this. The caret could be visible on entry to this function if the
778 // underlying edit control had re-created it automatically (see comments in
779 // OnPaint()).
780 HideCaret();
781 // We use DestroyCaret()/CreateCaret() instead of simply HideCaret()/
782 // ShowCaret() because HideCaret() is not sticky across paint events, e.g. a
783 // window resize will effectively restore caret visibility, regardless of
784 // whether HideCaret() was called before. While we do catch and handle these
785 // paint events (see OnPaint()), it doesn't seem to be enough to simply call
786 // HideCaret() while handling them because of the unpredictability of this
787 // Windows API. According to the documentation, it should be a cumulative call
788 // e.g. 5 hide calls should be balanced by 5 show calls. We have not found
789 // this to be true, which may be explained by the fact that this API is called
790 // internally in Windows, as well.
791 ::DestroyCaret();
792 if (model()->is_focus_visible()) {
793 ::CreateCaret(m_hWnd, (HBITMAP) NULL, 1, font_.GetHeight());
794 // According to the Windows API documentation, a newly created caret needs
795 // ShowCaret to be visible.
796 ShowCaret();
797 }
768 } 798 }
769 799
770 void OmniboxViewWin::SetDropHighlightPosition(int position) { 800 void OmniboxViewWin::SetDropHighlightPosition(int position) {
771 if (drop_highlight_position_ != position) { 801 if (drop_highlight_position_ != position) {
772 RepaintDropHighlight(drop_highlight_position_); 802 RepaintDropHighlight(drop_highlight_position_);
773 drop_highlight_position_ = position; 803 drop_highlight_position_ = position;
774 RepaintDropHighlight(drop_highlight_position_); 804 RepaintDropHighlight(drop_highlight_position_);
775 } 805 }
776 } 806 }
777 807
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 // First, give other handlers a chance to handle the message to see if we are 1764 // First, give other handlers a chance to handle the message to see if we are
1735 // actually going to activate and gain focus. 1765 // actually going to activate and gain focus.
1736 LRESULT result = DefWindowProc(WM_MOUSEACTIVATE, 1766 LRESULT result = DefWindowProc(WM_MOUSEACTIVATE,
1737 reinterpret_cast<WPARAM>(window), 1767 reinterpret_cast<WPARAM>(window),
1738 MAKELPARAM(hit_test, mouse_message)); 1768 MAKELPARAM(hit_test, mouse_message));
1739 // Check if we're getting focus from a click. We have to do this here rather 1769 // Check if we're getting focus from a click. We have to do this here rather
1740 // than in OnXButtonDown() since in many scenarios OnSetFocus() will be 1770 // than in OnXButtonDown() since in many scenarios OnSetFocus() will be
1741 // reached before OnXButtonDown(), preventing us from detecting this properly 1771 // reached before OnXButtonDown(), preventing us from detecting this properly
1742 // there. Also in those cases, we need to already know in OnSetFocus() that 1772 // there. Also in those cases, we need to already know in OnSetFocus() that
1743 // we should not restore the saved selection. 1773 // we should not restore the saved selection.
1744 if (!model()->has_focus() && 1774 if (((mouse_message == WM_LBUTTONDOWN || mouse_message == WM_RBUTTONDOWN)) &&
1745 ((mouse_message == WM_LBUTTONDOWN || mouse_message == WM_RBUTTONDOWN)) &&
1746 (result == MA_ACTIVATE)) { 1775 (result == MA_ACTIVATE)) {
1747 if (gaining_focus_) { 1776 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
1748 // On Windows 8 in metro mode, we get two WM_MOUSEACTIVATE messages when 1777 if (!model()->is_caret_visible()) {
1749 // we click on the omnibox with the mouse. 1778 // Explicitely setting visibility of the focus as a result of directly
1750 DCHECK(base::win::IsMetroProcess()); 1779 // clicking on the omnibox while it has invisible focus.
1751 return result; 1780 SetCaretVisibility(true);
1781 }
1782 } else {
1783 if (gaining_focus_) {
1784 // On Windows 8 in metro mode, we get two WM_MOUSEACTIVATE messages when
1785 // we click on the omnibox with the mouse.
1786 DCHECK(base::win::IsMetroProcess());
1787 return result;
1788 }
1789 gaining_focus_.reset(new ScopedFreeze(this, GetTextObjectModel()));
1790 // NOTE: Despite |mouse_message| being WM_XBUTTONDOWN here, we're not
1791 // guaranteed to call OnXButtonDown() later! Specifically, if this is the
1792 // second click of a double click, we'll reach here but later call
1793 // OnXButtonDblClk(). Make sure |gaining_focus_| gets reset both places,
1794 // or we'll have visual glitchiness and then DCHECK failures.
1795
1796 // Don't restore saved selection, it will just screw up our interaction
1797 // with this edit.
1798 saved_selection_for_focus_change_.cpMin = -1;
1752 } 1799 }
1753 gaining_focus_.reset(new ScopedFreeze(this, GetTextObjectModel()));
1754 // NOTE: Despite |mouse_message| being WM_XBUTTONDOWN here, we're not
1755 // guaranteed to call OnXButtonDown() later! Specifically, if this is the
1756 // second click of a double click, we'll reach here but later call
1757 // OnXButtonDblClk(). Make sure |gaining_focus_| gets reset both places,
1758 // or we'll have visual glitchiness and then DCHECK failures.
1759
1760 // Don't restore saved selection, it will just screw up our interaction
1761 // with this edit.
1762 saved_selection_for_focus_change_.cpMin = -1;
1763 } 1800 }
1764 return result; 1801 return result;
1765 } 1802 }
1766 1803
1767 void OmniboxViewWin::OnMouseMove(UINT keys, const CPoint& point) { 1804 void OmniboxViewWin::OnMouseMove(UINT keys, const CPoint& point) {
1768 if (possible_drag_) { 1805 if (possible_drag_) {
1769 StartDragIfNecessary(point); 1806 StartDragIfNecessary(point);
1770 // Don't fall through to default mouse handling, otherwise a second 1807 // Don't fall through to default mouse handling, otherwise a second
1771 // drag session may start. 1808 // drag session may start.
1772 return; 1809 return;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 1929
1893 // Draw the drop highlight. 1930 // Draw the drop highlight.
1894 if (drop_highlight_position_ != -1) 1931 if (drop_highlight_position_ != -1)
1895 DrawDropHighlight(memory_dc, rect, paint_clip_rect); 1932 DrawDropHighlight(memory_dc, rect, paint_clip_rect);
1896 1933
1897 // Blit the memory DC to the actual paint DC and clean up. 1934 // Blit the memory DC to the actual paint DC and clean up.
1898 BitBlt(paint_dc, rect.left, rect.top, rect.Width(), rect.Height(), memory_dc, 1935 BitBlt(paint_dc, rect.left, rect.top, rect.Width(), rect.Height(), memory_dc,
1899 rect.left, rect.top, SRCCOPY); 1936 rect.left, rect.top, SRCCOPY);
1900 memory_dc.SelectBitmap(old_bitmap); 1937 memory_dc.SelectBitmap(old_bitmap);
1901 edit_hwnd = old_edit_hwnd; 1938 edit_hwnd = old_edit_hwnd;
1939
1940 // This needs to be called regardless of the current state of the caret, even
1941 // if reaffirming a current state (hidden or shown). This is because the
1942 // underlying edit control will automatically re-create the caret when it
1943 // receives certain events that trigger repaints, e.g. window resize events.
1944 ApplyCaretVisibility();
1902 } 1945 }
1903 1946
1904 void OmniboxViewWin::OnPaste() { 1947 void OmniboxViewWin::OnPaste() {
1905 // Replace the selection if we have something to paste. 1948 // Replace the selection if we have something to paste.
1906 const string16 text(GetClipboardText()); 1949 const string16 text(GetClipboardText());
1907 if (!text.empty()) { 1950 if (!text.empty()) {
1908 // Record this paste, so we can do different behavior. 1951 // Record this paste, so we can do different behavior.
1909 model()->on_paste(); 1952 model()->on_paste();
1910 // Force a Paste operation to trigger the text_changed code in 1953 // Force a Paste operation to trigger the text_changed code in
1911 // OnAfterPossibleChange(), even if identical contents are pasted into the 1954 // OnAfterPossibleChange(), even if identical contents are pasted into the
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 return (rect.left - client_rect.left) + (client_rect.right - rect.right); 2794 return (rect.left - client_rect.left) + (client_rect.right - rect.right);
2752 } 2795 }
2753 2796
2754 int OmniboxViewWin::WidthNeededToDisplay(const string16& text) const { 2797 int OmniboxViewWin::WidthNeededToDisplay(const string16& text) const {
2755 // Use font_.GetStringWidth() instead of 2798 // Use font_.GetStringWidth() instead of
2756 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is 2799 // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is
2757 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout, 2800 // apparently buggy. In both LTR UI and RTL UI with left-to-right layout,
2758 // PosFromChar(i) might return 0 when i is greater than 1. 2801 // PosFromChar(i) might return 0 when i is greater than 1.
2759 return font_.GetStringWidth(text) + GetHorizontalMargin(); 2802 return font_.GetStringWidth(text) + GetHorizontalMargin();
2760 } 2803 }
OLDNEW
« 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