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

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

Issue 200131: Fix issue 21587, a regression of CL 196020.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 #include <gdk/gdkkeysyms.h> 8 #include <gdk/gdkkeysyms.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 scheme_security_level_(ToolbarModel::NORMAL), 101 scheme_security_level_(ToolbarModel::NORMAL),
102 mark_set_handler_id_(0), 102 mark_set_handler_id_(0),
103 button_1_pressed_(false), 103 button_1_pressed_(false),
104 text_selected_during_click_(false), 104 text_selected_during_click_(false),
105 text_view_focused_before_button_press_(false), 105 text_view_focused_before_button_press_(false),
106 #if !defined(TOOLKIT_VIEWS) 106 #if !defined(TOOLKIT_VIEWS)
107 theme_provider_(GtkThemeProvider::GetFrom(profile)), 107 theme_provider_(GtkThemeProvider::GetFrom(profile)),
108 #endif 108 #endif
109 enter_was_pressed_(false), 109 enter_was_pressed_(false),
110 tab_was_pressed_(false), 110 tab_was_pressed_(false),
111 paste_clipboard_requested_(false) { 111 paste_clipboard_requested_(false),
112 enter_was_inserted_(false) {
112 model_->SetPopupModel(popup_view_->GetModel()); 113 model_->SetPopupModel(popup_view_->GetModel());
113 } 114 }
114 115
115 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() { 116 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() {
116 NotificationService::current()->Notify( 117 NotificationService::current()->Notify(
117 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, 118 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
118 Source<AutocompleteEditViewGtk>(this), 119 Source<AutocompleteEditViewGtk>(this),
119 NotificationService::NoDetails()); 120 NotificationService::NoDetails());
120 121
121 // Explicitly teardown members which have a reference to us. Just to be safe 122 // Explicitly teardown members which have a reference to us. Just to be safe
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 text_before_change_ = GetText(); 456 text_before_change_ = GetText();
456 sel_before_change_ = GetSelection(); 457 sel_before_change_ = GetSelection();
457 } 458 }
458 459
459 // TODO(deanm): This is mostly stolen from Windows, and will need some work. 460 // TODO(deanm): This is mostly stolen from Windows, and will need some work.
460 bool AutocompleteEditViewGtk::OnAfterPossibleChange() { 461 bool AutocompleteEditViewGtk::OnAfterPossibleChange() {
461 // If the change is caused by an Enter key press event, and the event was not 462 // If the change is caused by an Enter key press event, and the event was not
462 // handled by IME, then it's an unexpected change and shall be reverted here. 463 // handled by IME, then it's an unexpected change and shall be reverted here.
463 // {Start|Finish}UpdatingHighlightedText() are called here to prevent the 464 // {Start|Finish}UpdatingHighlightedText() are called here to prevent the
464 // PRIMARY selection from being changed. 465 // PRIMARY selection from being changed.
465 if (enter_was_pressed_ && 466 if (enter_was_pressed_ && enter_was_inserted_) {
466 (char_inserted_ == '\n' || char_inserted_ == '\r')) {
467 StartUpdatingHighlightedText(); 467 StartUpdatingHighlightedText();
468 SetTextAndSelectedRange(text_before_change_, sel_before_change_); 468 SetTextAndSelectedRange(text_before_change_, sel_before_change_);
469 FinishUpdatingHighlightedText(); 469 FinishUpdatingHighlightedText();
470 return false; 470 return false;
471 } 471 }
472 472
473 CharRange new_sel = GetSelection(); 473 CharRange new_sel = GetSelection();
474 int length = GetTextLength(); 474 int length = GetTextLength();
475 bool selection_differs = (new_sel.cp_min != sel_before_change_.cp_min) || 475 bool selection_differs = (new_sel.cp_min != sel_before_change_.cp_min) ||
476 (new_sel.cp_max != sel_before_change_.cp_max); 476 (new_sel.cp_max != sel_before_change_.cp_max);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 // handler will delete current selection range and insert '\n' and always 590 // handler will delete current selection range and insert '\n' and always
591 // return TRUE. We need to prevent |text_view_| from performing this default 591 // return TRUE. We need to prevent |text_view_| from performing this default
592 // action if IME did not handle the key event, because we don't want the 592 // action if IME did not handle the key event, because we don't want the
593 // content of omnibox to be changed before triggering our special behavior. 593 // content of omnibox to be changed before triggering our special behavior.
594 // Otherwise our special behavior would not be performed correctly. 594 // Otherwise our special behavior would not be performed correctly.
595 // 595 //
596 // But there is no way for us to prevent GtkTextView from handling the key 596 // But there is no way for us to prevent GtkTextView from handling the key
597 // event and performing built-in operation. So in order to achieve our goal, 597 // event and performing built-in operation. So in order to achieve our goal,
598 // "insert-text" signal of |text_buffer_| object is intercepted, and 598 // "insert-text" signal of |text_buffer_| object is intercepted, and
599 // following actions are done in the signal handler: 599 // following actions are done in the signal handler:
600 // - If there is only one character in inserted text, save it in 600 // - If there is only one character in inserted text, and it's '\n' or '\r',
601 // char_inserted_. 601 // then set |enter_was_inserted_| to true.
602 // - Filter out all new line and tab characters. 602 // - Filter out all new line and tab characters.
603 // 603 //
604 // So if |char_inserted_| equals '\n' after calling |text_view_|'s 604 // So if |enter_was_inserted_| is true after calling |text_view_|'s default
605 // default signal handler against an Enter key press event, then we know that 605 // signal handler against an Enter key press event, then we know that the
606 // the Enter key press event was handled by GtkTextView rather than IME, and 606 // Enter key press event was handled by GtkTextView rather than IME, and can
607 // can perform the special behavior for Enter key safely. 607 // perform the special behavior for Enter key safely.
608 // 608 //
609 // Now the last thing is to prevent the content of omnibox from being changed 609 // Now the last thing is to prevent the content of omnibox from being changed
610 // by GtkTextView when Enter key is pressed. As OnBeforePossibleChange() and 610 // by GtkTextView when Enter key is pressed. As OnBeforePossibleChange() and
611 // OnAfterPossibleChange() will be called by GtkTextView before and after 611 // OnAfterPossibleChange() will be called by GtkTextView before and after
612 // changing the content, and the content is already saved in 612 // changing the content, and the content is already saved in
613 // OnBeforePossibleChange(), so if the Enter key press event was not handled 613 // OnBeforePossibleChange(), so if the Enter key press event was not handled
614 // by IME, it's easy to restore the content in OnAfterPossibleChange(), as if 614 // by IME, it's easy to restore the content in OnAfterPossibleChange(), as if
615 // it's not changed at all. 615 // it's not changed at all.
616 616
617 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget); 617 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget);
618 618
619 enter_was_pressed_ = (event->keyval == GDK_Return || 619 enter_was_pressed_ = (event->keyval == GDK_Return ||
620 event->keyval == GDK_ISO_Enter || 620 event->keyval == GDK_ISO_Enter ||
621 event->keyval == GDK_KP_Enter); 621 event->keyval == GDK_KP_Enter);
622 622
623 // Set |tab_was_pressed_| to true if it's a Tab key press event, so that our 623 // Set |tab_was_pressed_| to true if it's a Tab key press event, so that our
624 // handler of "move-focus" signal can trigger Tab to search behavior when 624 // handler of "move-focus" signal can trigger Tab to search behavior when
625 // necessary. 625 // necessary.
626 tab_was_pressed_ = ((event->keyval == GDK_Tab || 626 tab_was_pressed_ = ((event->keyval == GDK_Tab ||
627 event->keyval == GDK_ISO_Left_Tab || 627 event->keyval == GDK_ISO_Left_Tab ||
628 event->keyval == GDK_KP_Tab) && 628 event->keyval == GDK_KP_Tab) &&
629 !(event->state & GDK_CONTROL_MASK)); 629 !(event->state & GDK_CONTROL_MASK));
630 630
631 // Reset |char_inserted_|, which may be set in the "insert-text" signal 631 // Reset |enter_was_inserted_|, which may be set in the "insert-text" signal
632 // handler, so that we'll know if an Enter key event was handled by IME. 632 // handler, so that we'll know if an Enter key event was handled by IME.
633 char_inserted_ = 0; 633 enter_was_inserted_ = false;
634 634
635 // Reset |paste_clipboard_requested_| to make sure we won't misinterpret this 635 // Reset |paste_clipboard_requested_| to make sure we won't misinterpret this
636 // key input action as a paste action. 636 // key input action as a paste action.
637 paste_clipboard_requested_ = false; 637 paste_clipboard_requested_ = false;
638 638
639 // Call the default handler, so that IME can work as normal. 639 // Call the default handler, so that IME can work as normal.
640 // New line characters will be filtered out by our "insert-text" 640 // New line characters will be filtered out by our "insert-text"
641 // signal handler attached to |text_buffer_| object. 641 // signal handler attached to |text_buffer_| object.
642 gboolean result = klass->key_press_event(widget, event); 642 gboolean result = klass->key_press_event(widget, event);
643 643
644 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can 644 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can
645 // only be triggered by pressing Tab key. 645 // only be triggered by pressing Tab key.
646 tab_was_pressed_ = false; 646 tab_was_pressed_ = false;
647 647
648 if (enter_was_pressed_ && 648 if (enter_was_pressed_ && enter_was_inserted_) {
649 (char_inserted_ == '\n' || char_inserted_ == '\r')) {
650 bool alt_held = (event->state & GDK_MOD1_MASK); 649 bool alt_held = (event->state & GDK_MOD1_MASK);
651 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); 650 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
652 result = TRUE; 651 result = TRUE;
653 } else if (!result && event->keyval == GDK_Escape && 652 } else if (!result && event->keyval == GDK_Escape &&
654 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) { 653 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) {
655 // We can handle the Escape key if |text_view_| did not handle it. 654 // We can handle the Escape key if |text_view_| did not handle it.
656 // If it's not handled by us, then we need to propagate it up to the parent 655 // If it's not handled by us, then we need to propagate it up to the parent
657 // widgets, so that Escape accelerator can still work. 656 // widgets, so that Escape accelerator can still work.
658 result = model_->OnEscapeKeyPressed(); 657 result = model_->OnEscapeKeyPressed();
659 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { 658 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 filtered_text.reserve(len); 932 filtered_text.reserve(len);
934 933
935 // Filter out new line and tab characters. 934 // Filter out new line and tab characters.
936 // |text| is guaranteed to be a valid UTF-8 string, so it's safe here to 935 // |text| is guaranteed to be a valid UTF-8 string, so it's safe here to
937 // filter byte by byte. 936 // filter byte by byte.
938 // 937 //
939 // If there was only a single character, then it might be generated by a key 938 // If there was only a single character, then it might be generated by a key
940 // event. In this case, we save the single character to help our 939 // event. In this case, we save the single character to help our
941 // "key-press-event" signal handler distinguish if an Enter key event is 940 // "key-press-event" signal handler distinguish if an Enter key event is
942 // handled by IME or not. 941 // handled by IME or not.
943 if (len == 1) 942 if (len == 1 && (text[0] == '\n' || text[0] == '\r'))
944 char_inserted_ = text[0]; 943 enter_was_inserted_ = true;
945 944
946 for (gint i = 0; i < len; ++i) { 945 for (gint i = 0; i < len; ++i) {
947 gchar c = text[i]; 946 gchar c = text[i];
948 if (c == '\n' || c == '\r' || c == '\t') 947 if (c == '\n' || c == '\r' || c == '\t')
949 continue; 948 continue;
950 949
951 filtered_text.push_back(c); 950 filtered_text.push_back(c);
952 } 951 }
953 952
954 if (filtered_text.length()) { 953 if (filtered_text.length()) {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 std::string utf8 = WideToUTF8(text); 1175 std::string utf8 = WideToUTF8(text);
1177 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length()); 1176 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length());
1178 SetSelectedRange(range); 1177 SetSelectedRange(range);
1179 } 1178 }
1180 1179
1181 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { 1180 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) {
1182 GtkTextIter insert, bound; 1181 GtkTextIter insert, bound;
1183 ItersFromCharRange(range, &bound, &insert); 1182 ItersFromCharRange(range, &bound, &insert);
1184 gtk_text_buffer_select_range(text_buffer_, &insert, &bound); 1183 gtk_text_buffer_select_range(text_buffer_, &insert, &bound);
1185 } 1184 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698