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

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc

Issue 5966006: Hitting Tab should always move cursor to end of omnibox text. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix AutocompleteEditViewViews. Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/autocomplete/autocomplete_edit_view_gtk.h" 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
6 6
7 #include <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 ) { 772 ) {
773 instant_animation_->set_delegate(this); 773 instant_animation_->set_delegate(this);
774 instant_animation_->Start(); 774 instant_animation_->Start();
775 } 775 }
776 776
777 gtk_widget_show(instant_view_); 777 gtk_widget_show(instant_view_);
778 AdjustVerticalAlignmentOfInstantView(); 778 AdjustVerticalAlignmentOfInstantView();
779 UpdateInstantViewColors(); 779 UpdateInstantViewColors();
780 } 780 }
781 781
782 string16 AutocompleteEditViewGtk::GetInstantSuggestion() const {
783 const gchar* suggestion = gtk_label_get_text(GTK_LABEL(instant_view_));
784 return suggestion ? UTF8ToUTF16(suggestion) : string16();
785 }
786
782 int AutocompleteEditViewGtk::TextWidth() const { 787 int AutocompleteEditViewGtk::TextWidth() const {
783 int horizontal_border_size = 788 int horizontal_border_size =
784 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), 789 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_),
785 GTK_TEXT_WINDOW_LEFT) + 790 GTK_TEXT_WINDOW_LEFT) +
786 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), 791 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_),
787 GTK_TEXT_WINDOW_RIGHT) + 792 GTK_TEXT_WINDOW_RIGHT) +
788 gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + 793 gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) +
789 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); 794 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_));
790 795
791 GtkTextIter start, end; 796 GtkTextIter start, end;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 832
828 #if defined(TOOLKIT_VIEWS) 833 #if defined(TOOLKIT_VIEWS)
829 views::View* AutocompleteEditViewGtk::AddToView(views::View* parent) { 834 views::View* AutocompleteEditViewGtk::AddToView(views::View* parent) {
830 views::NativeViewHost* host = new views::NativeViewHost; 835 views::NativeViewHost* host = new views::NativeViewHost;
831 parent->AddChildView(host); 836 parent->AddChildView(host);
832 host->set_focus_view(parent); 837 host->set_focus_view(parent);
833 host->Attach(GetNativeView()); 838 host->Attach(GetNativeView());
834 return host; 839 return host;
835 } 840 }
836 841
837 bool AutocompleteEditViewGtk::CommitInstantSuggestion(
838 const string16& typed_text,
839 const string16& suggestion) {
840 return CommitInstantSuggestion();
841 }
842
843 void AutocompleteEditViewGtk::EnableAccessibility() { 842 void AutocompleteEditViewGtk::EnableAccessibility() {
844 accessible_widget_helper_.reset( 843 accessible_widget_helper_.reset(
845 new AccessibleWidgetHelper(text_view(), model_->profile())); 844 new AccessibleWidgetHelper(text_view(), model_->profile()));
846 accessible_widget_helper_->SetWidgetName( 845 accessible_widget_helper_->SetWidgetName(
847 text_view(), l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); 846 text_view(), l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION));
848 } 847 }
849 848
850 // static 849 // static
851 AutocompleteEditView* AutocompleteEditViewGtk::Create( 850 AutocompleteEditView* AutocompleteEditViewGtk::Create(
852 AutocompleteEditController* controller, 851 AutocompleteEditController* controller,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 890
892 void AutocompleteEditViewGtk::Observe(NotificationType type, 891 void AutocompleteEditViewGtk::Observe(NotificationType type,
893 const NotificationSource& source, 892 const NotificationSource& source,
894 const NotificationDetails& details) { 893 const NotificationDetails& details) {
895 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); 894 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED);
896 895
897 SetBaseColor(); 896 SetBaseColor();
898 } 897 }
899 898
900 void AutocompleteEditViewGtk::AnimationEnded(const ui::Animation* animation) { 899 void AutocompleteEditViewGtk::AnimationEnded(const ui::Animation* animation) {
901 controller_->OnCommitSuggestedText(GetText()); 900 controller_->OnCommitSuggestedText(false);
902 } 901 }
903 902
904 void AutocompleteEditViewGtk::AnimationProgressed( 903 void AutocompleteEditViewGtk::AnimationProgressed(
905 const ui::Animation* animation) { 904 const ui::Animation* animation) {
906 UpdateInstantViewColors(); 905 UpdateInstantViewColors();
907 } 906 }
908 907
909 void AutocompleteEditViewGtk::AnimationCanceled( 908 void AutocompleteEditViewGtk::AnimationCanceled(
910 const ui::Animation* animation) { 909 const ui::Animation* animation) {
911 UpdateInstantViewColors(); 910 UpdateInstantViewColors();
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 GtkMovementStep step, 1336 GtkMovementStep step,
1338 gint count, 1337 gint count,
1339 gboolean extend_selection) { 1338 gboolean extend_selection) {
1340 GtkTextIter sel_start, sel_end; 1339 GtkTextIter sel_start, sel_end;
1341 gboolean has_selection = 1340 gboolean has_selection =
1342 gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end); 1341 gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end);
1343 bool handled = false; 1342 bool handled = false;
1344 1343
1345 if (step == GTK_MOVEMENT_VISUAL_POSITIONS && !extend_selection && 1344 if (step == GTK_MOVEMENT_VISUAL_POSITIONS && !extend_selection &&
1346 (count == 1 || count == -1)) { 1345 (count == 1 || count == -1)) {
1347 gint cursor_pos;
1348 g_object_get(G_OBJECT(text_buffer_), "cursor-position", &cursor_pos, NULL);
1349
1350 // We need to take the content direction into account when handling cursor 1346 // We need to take the content direction into account when handling cursor
1351 // movement, because the behavior of Left and Right key will be inverted if 1347 // movement, because the behavior of Left and Right key will be inverted if
1352 // the direction is RTL. Although we should check the direction around the 1348 // the direction is RTL. Although we should check the direction around the
1353 // input caret, it's much simpler and good enough to check whole content's 1349 // input caret, it's much simpler and good enough to check whole content's
1354 // direction. 1350 // direction.
1355 PangoDirection content_dir = GetContentDirection(); 1351 PangoDirection content_dir = GetContentDirection();
1356 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1; 1352 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1;
1357 1353
1358 // We want the GtkEntry behavior when you move the cursor while you have a 1354 // We want the GtkEntry behavior when you move the cursor while you have a
1359 // selection. GtkTextView just drops the selection and moves the cursor, 1355 // selection. GtkTextView just drops the selection and moves the cursor,
1360 // but instead we want to move the cursor to the appropiate end of the 1356 // but instead we want to move the cursor to the appropiate end of the
1361 // selection. 1357 // selection.
1362 if (has_selection) { 1358 if (has_selection) {
1363 // We have a selection and start / end are in ascending order. 1359 // We have a selection and start / end are in ascending order.
1364 // Cursor placement will remove the selection, so we need inform 1360 // Cursor placement will remove the selection, so we need inform
1365 // |model_| about this change by 1361 // |model_| about this change by
1366 // calling On{Before|After}PossibleChange() methods. 1362 // calling On{Before|After}PossibleChange() methods.
1367 OnBeforePossibleChange(); 1363 OnBeforePossibleChange();
1368 gtk_text_buffer_place_cursor( 1364 gtk_text_buffer_place_cursor(
1369 text_buffer_, count == count_towards_end ? &sel_end : &sel_start); 1365 text_buffer_, count == count_towards_end ? &sel_end : &sel_start);
1370 OnAfterPossibleChange(); 1366 OnAfterPossibleChange();
1371 handled = true; 1367 handled = true;
1372 } else if (count == count_towards_end && cursor_pos == GetTextLength()) { 1368 } else if (count == count_towards_end &&
1373 handled = controller_->OnCommitSuggestedText(GetText()); 1369 GetCursorPosition() == GetTextLength()) {
1370 handled = controller_->OnCommitSuggestedText(true);
1374 } 1371 }
1375 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down. 1372 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down.
1376 // Multiply by count for the direction (if we move too much that's ok). 1373 // Multiply by count for the direction (if we move too much that's ok).
1377 model_->OnUpOrDownKeyPressed(model_->result().size() * count); 1374 model_->OnUpOrDownKeyPressed(model_->result().size() * count);
1378 handled = true; 1375 handled = true;
1379 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down. 1376 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down.
1380 model_->OnUpOrDownKeyPressed(count); 1377 model_->OnUpOrDownKeyPressed(count);
1381 handled = true; 1378 handled = true;
1382 } 1379 }
1383 1380
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget, 1628 void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget,
1632 GtkDirectionType direction) { 1629 GtkDirectionType direction) {
1633 if (!tab_was_pressed_) 1630 if (!tab_was_pressed_)
1634 return; 1631 return;
1635 1632
1636 // If special behavior is triggered, then stop the signal emission to 1633 // If special behavior is triggered, then stop the signal emission to
1637 // prevent the focus from being moved. 1634 // prevent the focus from being moved.
1638 bool handled = false; 1635 bool handled = false;
1639 1636
1640 // Trigger Tab to search behavior only when Tab key is pressed. 1637 // Trigger Tab to search behavior only when Tab key is pressed.
1641 if (model_->is_keyword_hint()) { 1638 if (model_->is_keyword_hint())
1642 handled = model_->AcceptKeyword(); 1639 handled = model_->AcceptKeyword();
1643 } else if (GTK_WIDGET_VISIBLE(instant_view_)) { 1640
1644 controller_->OnCommitSuggestedText(GetText()); 1641 #if GTK_CHECK_VERSION(2, 20, 0)
1642 if (!handled && !preedit_.empty())
1645 handled = true; 1643 handled = true;
1646 } else { 1644 #endif
1645
1646 if (!handled && GTK_WIDGET_VISIBLE(instant_view_))
1647 handled = controller_->OnCommitSuggestedText(true);
1648
1649 if (!handled) {
1650 CharRange selection = GetSelection();
1651 int length = GetTextLength();
1652 if (selection.cp_min != selection.cp_max || selection.cp_min < length) {
1653 OnBeforePossibleChange();
sky 2011/01/27 19:55:31 Do we need the OnBefore/after here?
James Su 2011/01/27 20:07:16 Yes we need it to inform the model possible select
1654 SetCursorPosition(length);
1655 OnAfterPossibleChange();
1656 handled = true;
1657 }
1658 }
1659
1660 if (!handled)
1647 handled = controller_->AcceptCurrentInstantPreview(); 1661 handled = controller_->AcceptCurrentInstantPreview();
1648 }
1649 1662
1650 if (handled) { 1663 if (handled) {
1651 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); 1664 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
1652 g_signal_stop_emission(widget, signal_id, 0); 1665 g_signal_stop_emission(widget, signal_id, 0);
1653 } 1666 }
1654 } 1667 }
1655 1668
1656 void AutocompleteEditViewGtk::HandleCopyClipboard(GtkWidget* sender) { 1669 void AutocompleteEditViewGtk::HandleCopyClipboard(GtkWidget* sender) {
1657 HandleCopyOrCutClipboard(true); 1670 HandleCopyOrCutClipboard(true);
1658 } 1671 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); 1877 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_);
1865 #if GTK_CHECK_VERSION(2, 20, 0) 1878 #if GTK_CHECK_VERSION(2, 20, 0)
1866 // We need to count the length of the text being composed, because we treat 1879 // We need to count the length of the text being composed, because we treat
1867 // it as part of the content in GetText(). 1880 // it as part of the content in GetText().
1868 return gtk_text_iter_get_offset(&end) + preedit_.size(); 1881 return gtk_text_iter_get_offset(&end) + preedit_.size();
1869 #else 1882 #else
1870 return gtk_text_iter_get_offset(&end); 1883 return gtk_text_iter_get_offset(&end);
1871 #endif 1884 #endif
1872 } 1885 }
1873 1886
1887 int AutocompleteEditViewGtk::GetCursorPosition() const {
1888 gint cursor_pos;
sky 2011/01/27 19:55:31 Can this be implemented in terms of GetSelection?
James Su 2011/01/27 20:07:16 I'll recheck this part to see how we can do it bet
1889 g_object_get(G_OBJECT(text_buffer_), "cursor-position", &cursor_pos, NULL);
1890 return cursor_pos;
1891 }
1892
1893 void AutocompleteEditViewGtk::SetCursorPosition(int cursor_position) {
1894 GtkTextIter cursor;
1895 gtk_text_buffer_get_iter_at_offset(text_buffer_, &cursor, cursor_position);
1896 gtk_text_buffer_place_cursor(text_buffer_, &cursor);
1897 }
1898
1874 void AutocompleteEditViewGtk::EmphasizeURLComponents() { 1899 void AutocompleteEditViewGtk::EmphasizeURLComponents() {
1875 #if GTK_CHECK_VERSION(2, 20, 0) 1900 #if GTK_CHECK_VERSION(2, 20, 0)
1876 // We can't change the text style easily, if the preedit string (the text 1901 // We can't change the text style easily, if the preedit string (the text
1877 // being composed by the input method) is not empty, which is not treated as 1902 // being composed by the input method) is not empty, which is not treated as
1878 // a part of the text content inside GtkTextView. And it's ok to simply return 1903 // a part of the text content inside GtkTextView. And it's ok to simply return
1879 // in this case, as this method will be called again when the preedit string 1904 // in this case, as this method will be called again when the preedit string
1880 // gets committed. 1905 // gets committed.
1881 if (preedit_.size()) { 1906 if (preedit_.size()) {
1882 strikethrough_ = CharRange(); 1907 strikethrough_ = CharRange();
1883 return; 1908 return;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 } 1964 }
1940 } 1965 }
1941 1966
1942 void AutocompleteEditViewGtk::StopAnimation() { 1967 void AutocompleteEditViewGtk::StopAnimation() {
1943 // Clear the animation delegate so we don't get an AnimationEnded() callback. 1968 // Clear the animation delegate so we don't get an AnimationEnded() callback.
1944 instant_animation_->set_delegate(NULL); 1969 instant_animation_->set_delegate(NULL);
1945 instant_animation_->Stop(); 1970 instant_animation_->Stop();
1946 UpdateInstantViewColors(); 1971 UpdateInstantViewColors();
1947 } 1972 }
1948 1973
1949 bool AutocompleteEditViewGtk::CommitInstantSuggestion() {
1950 const gchar* suggestion = gtk_label_get_text(GTK_LABEL(instant_view_));
1951 if (!suggestion || !*suggestion)
1952 return false;
1953
1954 model()->FinalizeInstantQuery(GetText(),
1955 UTF8ToUTF16(suggestion));
1956 return true;
1957 }
1958
1959 void AutocompleteEditViewGtk::TextChanged() { 1974 void AutocompleteEditViewGtk::TextChanged() {
1960 EmphasizeURLComponents(); 1975 EmphasizeURLComponents();
1961 controller_->OnChanged(); 1976 controller_->OnChanged();
1962 } 1977 }
1963 1978
1964 void AutocompleteEditViewGtk::SavePrimarySelection( 1979 void AutocompleteEditViewGtk::SavePrimarySelection(
1965 const std::string& selected_text) { 1980 const std::string& selected_text) {
1966 GtkClipboard* clipboard = 1981 GtkClipboard* clipboard =
1967 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); 1982 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY);
1968 DCHECK(clipboard); 1983 DCHECK(clipboard);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 // baseline, so we need to move the |instant_view_| down to make sure it 2232 // baseline, so we need to move the |instant_view_| down to make sure it
2218 // has the same baseline as the |text_view_|. 2233 // has the same baseline as the |text_view_|.
2219 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); 2234 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_));
2220 int height; 2235 int height;
2221 pango_layout_get_size(layout, NULL, &height); 2236 pango_layout_get_size(layout, NULL, &height);
2222 PangoLayoutIter* iter = pango_layout_get_iter(layout); 2237 PangoLayoutIter* iter = pango_layout_get_iter(layout);
2223 int baseline = pango_layout_iter_get_baseline(iter); 2238 int baseline = pango_layout_iter_get_baseline(iter);
2224 pango_layout_iter_free(iter); 2239 pango_layout_iter_free(iter);
2225 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); 2240 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL);
2226 } 2241 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698