OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |