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

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 2322303002: Textfield: suppress cursor repaints when there's a selection (Closed)
Patch Set: refactor Created 4 years, 3 months 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 | « ui/views/controls/textfield/textfield.h ('k') | 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 "ui/views/controls/textfield/textfield.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 use_default_selection_background_color_(true), 248 use_default_selection_background_color_(true),
249 text_color_(SK_ColorBLACK), 249 text_color_(SK_ColorBLACK),
250 background_color_(SK_ColorWHITE), 250 background_color_(SK_ColorWHITE),
251 selection_text_color_(SK_ColorWHITE), 251 selection_text_color_(SK_ColorWHITE),
252 selection_background_color_(SK_ColorBLUE), 252 selection_background_color_(SK_ColorBLUE),
253 placeholder_text_color_(kDefaultPlaceholderTextColor), 253 placeholder_text_color_(kDefaultPlaceholderTextColor),
254 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 254 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
255 text_input_flags_(0), 255 text_input_flags_(0),
256 performing_user_action_(false), 256 performing_user_action_(false),
257 skip_input_method_cancel_composition_(false), 257 skip_input_method_cancel_composition_(false),
258 cursor_visible_(false), 258 editing_cursor_visible_(false),
Peter Kasting 2016/09/16 18:52:27 I still don't really know what "editing cursor vis
259 drop_cursor_visible_(false), 259 drop_cursor_visible_(false),
260 initiating_drag_(false), 260 initiating_drag_(false),
261 aggregated_clicks_(0), 261 aggregated_clicks_(0),
262 drag_start_display_offset_(0), 262 drag_start_display_offset_(0),
263 touch_handles_hidden_due_to_scroll_(false), 263 touch_handles_hidden_due_to_scroll_(false),
264 weak_ptr_factory_(this) { 264 weak_ptr_factory_(this) {
265 set_context_menu_controller(this); 265 set_context_menu_controller(this);
266 set_drag_controller(this); 266 set_drag_controller(this);
267 GetRenderText()->SetFontList(GetDefaultFontList()); 267 GetRenderText()->SetFontList(GetDefaultFontList());
268 SetBorder(std::unique_ptr<Border>(new FocusableBorder())); 268 SetBorder(std::unique_ptr<Border>(new FocusableBorder()));
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 } 967 }
968 968
969 void Textfield::OnPaint(gfx::Canvas* canvas) { 969 void Textfield::OnPaint(gfx::Canvas* canvas) {
970 OnPaintBackground(canvas); 970 OnPaintBackground(canvas);
971 PaintTextAndCursor(canvas); 971 PaintTextAndCursor(canvas);
972 OnPaintBorder(canvas); 972 OnPaintBorder(canvas);
973 } 973 }
974 974
975 void Textfield::OnFocus() { 975 void Textfield::OnFocus() {
976 GetRenderText()->set_focused(true); 976 GetRenderText()->set_focused(true);
977 cursor_visible_ = true; 977 editing_cursor_visible_ = true;
Peter Kasting 2016/09/16 18:52:27 Why not make this mutually exclusive with HasSelec
978 SchedulePaint(); 978 SchedulePaint();
979 if (GetInputMethod()) 979 if (GetInputMethod())
980 GetInputMethod()->SetFocusedTextInputClient(this); 980 GetInputMethod()->SetFocusedTextInputClient(this);
981 OnCaretBoundsChanged(); 981 OnCaretBoundsChanged();
982 982
983 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); 983 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs();
984 if (caret_blink_ms != 0) { 984 if (caret_blink_ms != 0 && !HasSelection()) {
985 cursor_repaint_timer_.Start(FROM_HERE, 985 cursor_repaint_timer_.Start(FROM_HERE,
986 base::TimeDelta::FromMilliseconds(caret_blink_ms), this, 986 base::TimeDelta::FromMilliseconds(caret_blink_ms), this,
987 &Textfield::UpdateCursor); 987 &Textfield::UpdateCursor);
988 } 988 }
989 989
990 View::OnFocus(); 990 View::OnFocus();
991 SchedulePaint(); 991 SchedulePaint();
992 } 992 }
993 993
994 void Textfield::OnBlur() { 994 void Textfield::OnBlur() {
995 GetRenderText()->set_focused(false); 995 GetRenderText()->set_focused(false);
996 if (GetInputMethod()) 996 if (GetInputMethod())
997 GetInputMethod()->DetachTextInputClient(this); 997 GetInputMethod()->DetachTextInputClient(this);
998 cursor_repaint_timer_.Stop(); 998 cursor_repaint_timer_.Stop();
999 if (cursor_visible_) { 999 if (editing_cursor_visible_) {
1000 cursor_visible_ = false; 1000 editing_cursor_visible_ = false;
1001 RepaintCursor(); 1001 RepaintCursor();
1002 } 1002 }
1003 1003
1004 DestroyTouchSelection(); 1004 DestroyTouchSelection();
1005 1005
1006 // Border typically draws focus indicator. 1006 // Border typically draws focus indicator.
1007 SchedulePaint(); 1007 SchedulePaint();
1008 } 1008 }
1009 1009
1010 gfx::Point Textfield::GetKeyboardContextMenuLocation() { 1010 gfx::Point Textfield::GetKeyboardContextMenuLocation() {
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 } 1780 }
1781 // Disable subpixel rendering when the background color is transparent 1781 // Disable subpixel rendering when the background color is transparent
1782 // because it draws incorrect colors around the glyphs in that case. 1782 // because it draws incorrect colors around the glyphs in that case.
1783 // See crbug.com/115198 1783 // See crbug.com/115198
1784 GetRenderText()->set_subpixel_rendering_suppressed( 1784 GetRenderText()->set_subpixel_rendering_suppressed(
1785 SkColorGetA(color) != SK_AlphaOPAQUE); 1785 SkColorGetA(color) != SK_AlphaOPAQUE);
1786 SchedulePaint(); 1786 SchedulePaint();
1787 } 1787 }
1788 1788
1789 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) { 1789 void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) {
1790 DCHECK(HasFocus());
1790 if (text_changed) { 1791 if (text_changed) {
1791 if (controller_) 1792 if (controller_)
1792 controller_->ContentsChanged(this, text()); 1793 controller_->ContentsChanged(this, text());
1793 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true); 1794 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
1794 } 1795 }
1795 if (cursor_changed) { 1796 if (cursor_changed) {
1796 cursor_visible_ = true; 1797 editing_cursor_visible_ = false;
1797 RepaintCursor(); 1798 RepaintCursor();
Peter Kasting 2016/09/16 18:52:27 Nit: Since RepaintCursor() merely schedules a pain
1798 if (cursor_repaint_timer_.IsRunning()) 1799
1800 // If this textfield is not focused, the timer must have been stopped in
1801 // |Textfield::OnBlur|, and this method needs to avoid accidentally
1802 // restarting it.
1803 if (!HasFocus())
1804 DCHECK(!cursor_repaint_timer_.IsRunning());
Peter Kasting 2016/09/16 18:52:27 Nit: Just: DCHECK(HasFocus() || !cursor_repai
1805
1806 // Cursor repaints are suppressed whenever there is a selection or this view
1807 // does not have focus. When the selection changes, the cursor moves, or
1808 // this view gains/loses focus, this method will get called with
1809 // |cursor_changed| set to true, and the timer will be restarted here.
1810 if (HasSelection()) {
Peter Kasting 2016/09/16 18:52:27 Nit: Inspired by my suggestion above to move the R
1811 cursor_repaint_timer_.Stop();
1812 } else if (HasFocus() && enabled() && !read_only()) {
1813 editing_cursor_visible_ = true;
1799 cursor_repaint_timer_.Reset(); 1814 cursor_repaint_timer_.Reset();
1815 }
1816
1800 if (!text_changed) { 1817 if (!text_changed) {
1801 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire 1818 // TEXT_CHANGED implies TEXT_SELECTION_CHANGED, so we only need to fire
1802 // this if only the selection changed. 1819 // this if only the selection changed.
1803 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true); 1820 NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true);
1804 } 1821 }
1805 } 1822 }
1806 if (text_changed || cursor_changed) { 1823 if (text_changed || cursor_changed) {
1807 OnCaretBoundsChanged(); 1824 OnCaretBoundsChanged();
1808 SchedulePaint(); 1825 SchedulePaint();
1809 } 1826 }
1810 } 1827 }
1811 1828
1812 void Textfield::UpdateCursor() { 1829 void Textfield::UpdateCursor() {
1813 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs(); 1830 const size_t caret_blink_ms = Textfield::GetCaretBlinkMs();
1814 cursor_visible_ = !cursor_visible_ || (caret_blink_ms == 0); 1831 editing_cursor_visible_ = !editing_cursor_visible_ || (caret_blink_ms == 0);
1815 RepaintCursor(); 1832 RepaintCursor();
1816 } 1833 }
1817 1834
1818 void Textfield::RepaintCursor() { 1835 void Textfield::RepaintCursor() {
1819 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds()); 1836 gfx::Rect r(GetRenderText()->GetUpdatedCursorBounds());
1820 r.Inset(-1, -1, -1, -1); 1837 r.Inset(-1, -1, -1, -1);
1821 SchedulePaintInRect(r); 1838 SchedulePaintInRect(r);
1822 } 1839 }
1823 1840
1824 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) { 1841 void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) {
1825 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor"); 1842 TRACE_EVENT0("views", "Textfield::PaintTextAndCursor");
1826 canvas->Save(); 1843 canvas->Save();
1827 1844
1828 // Draw placeholder text if needed. 1845 // Draw placeholder text if needed.
1829 gfx::RenderText* render_text = GetRenderText(); 1846 gfx::RenderText* render_text = GetRenderText();
1830 if (text().empty() && !GetPlaceholderText().empty()) { 1847 if (text().empty() && !GetPlaceholderText().empty()) {
1831 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(), 1848 canvas->DrawStringRect(GetPlaceholderText(), GetFontList(),
1832 ui::MaterialDesignController::IsSecondaryUiMaterial() 1849 ui::MaterialDesignController::IsSecondaryUiMaterial()
1833 ? SkColorSetA(GetTextColor(), 0x83) 1850 ? SkColorSetA(GetTextColor(), 0x83)
1834 : placeholder_text_color_, 1851 : placeholder_text_color_,
1835 render_text->display_rect()); 1852 render_text->display_rect());
1836 } 1853 }
1837 1854
1838 // Draw the text, cursor, and selection. 1855 // Draw the text, cursor, and selection.
1839 render_text->set_cursor_visible(cursor_visible_ && !drop_cursor_visible_ && 1856 render_text->set_cursor_visible(editing_cursor_visible_ &&
1857 !drop_cursor_visible_ &&
1840 !HasSelection()); 1858 !HasSelection());
1841 render_text->Draw(canvas); 1859 render_text->Draw(canvas);
1842 1860
1843 // Draw the detached drop cursor that marks where the text will be dropped. 1861 // Draw the detached drop cursor that marks where the text will be dropped.
1844 if (drop_cursor_visible_) 1862 if (drop_cursor_visible_)
1845 render_text->DrawCursor(canvas, drop_cursor_position_); 1863 render_text->DrawCursor(canvas, drop_cursor_position_);
1846 1864
1847 canvas->Restore(); 1865 canvas->Restore();
1848 } 1866 }
1849 1867
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 RequestFocus(); 2045 RequestFocus();
2028 model_->MoveCursorTo(mouse); 2046 model_->MoveCursorTo(mouse);
2029 if (!selection_clipboard_text.empty()) { 2047 if (!selection_clipboard_text.empty()) {
2030 model_->InsertText(selection_clipboard_text); 2048 model_->InsertText(selection_clipboard_text);
2031 UpdateAfterChange(true, true); 2049 UpdateAfterChange(true, true);
2032 } 2050 }
2033 OnAfterUserAction(); 2051 OnAfterUserAction();
2034 } 2052 }
2035 2053
2036 } // namespace views 2054 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/textfield.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698