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

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

Issue 196020: Fix issue 20934: Omnibox keyboard behavior wrong for "See recent pages in his... (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
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.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) 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 command_updater_(command_updater), 99 command_updater_(command_updater),
100 popup_window_mode_(popup_window_mode), 100 popup_window_mode_(popup_window_mode),
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 tab_was_pressed_(false), 110 tab_was_pressed_(false),
110 paste_clipboard_requested_(false) { 111 paste_clipboard_requested_(false) {
111 model_->SetPopupModel(popup_view_->GetModel()); 112 model_->SetPopupModel(popup_view_->GetModel());
112 } 113 }
113 114
114 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() { 115 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() {
115 NotificationService::current()->Notify( 116 NotificationService::current()->Notify(
116 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, 117 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
117 Source<AutocompleteEditViewGtk>(this), 118 Source<AutocompleteEditViewGtk>(this),
118 NotificationService::NoDetails()); 119 NotificationService::NoDetails());
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 model_->on_paste_replacing_all(); 456 model_->on_paste_replacing_all();
456 } 457 }
457 458
458 // Record our state. 459 // Record our state.
459 text_before_change_ = GetText(); 460 text_before_change_ = GetText();
460 sel_before_change_ = GetSelection(); 461 sel_before_change_ = GetSelection();
461 } 462 }
462 463
463 // TODO(deanm): This is mostly stolen from Windows, and will need some work. 464 // TODO(deanm): This is mostly stolen from Windows, and will need some work.
464 bool AutocompleteEditViewGtk::OnAfterPossibleChange() { 465 bool AutocompleteEditViewGtk::OnAfterPossibleChange() {
466 // If the change is caused by an Enter key press event, and the event was not
467 // handled by IME, then it's an unexpected change and shall be reverted here.
468 // {Start|Finish}UpdatingHighlightedText() are called here to prevent the
469 // PRIMARY selection from being changed.
470 if (enter_was_pressed_ &&
471 (char_inserted_ == '\n' || char_inserted_ == '\r')) {
472 StartUpdatingHighlightedText();
473 SetTextAndSelectedRange(text_before_change_, sel_before_change_);
474 FinishUpdatingHighlightedText();
475 return false;
476 }
477
465 CharRange new_sel = GetSelection(); 478 CharRange new_sel = GetSelection();
466 int length = GetTextLength(); 479 int length = GetTextLength();
467 bool selection_differs = (new_sel.cp_min != sel_before_change_.cp_min) || 480 bool selection_differs = (new_sel.cp_min != sel_before_change_.cp_min) ||
468 (new_sel.cp_max != sel_before_change_.cp_max); 481 (new_sel.cp_max != sel_before_change_.cp_max);
469 bool at_end_of_edit = (new_sel.cp_min == length && new_sel.cp_max == length); 482 bool at_end_of_edit = (new_sel.cp_min == length && new_sel.cp_max == length);
470 483
471 // See if the text or selection have changed since OnBeforePossibleChange(). 484 // See if the text or selection have changed since OnBeforePossibleChange().
472 std::wstring new_text(GetText()); 485 std::wstring new_text(GetText());
473 bool text_differs = (new_text != text_before_change_); 486 bool text_differs = (new_text != text_before_change_);
474 487
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 // - If there is only one character in inserted text, save it in 605 // - If there is only one character in inserted text, save it in
593 // char_inserted_. 606 // char_inserted_.
594 // - Filter out all new line and tab characters. 607 // - Filter out all new line and tab characters.
595 // 608 //
596 // So if |char_inserted_| equals '\n' after calling |text_view_|'s 609 // So if |char_inserted_| equals '\n' after calling |text_view_|'s
597 // default signal handler against an Enter key press event, then we know that 610 // default signal handler against an Enter key press event, then we know that
598 // the Enter key press event was handled by GtkTextView rather than IME, and 611 // the Enter key press event was handled by GtkTextView rather than IME, and
599 // can perform the special behavior for Enter key safely. 612 // can perform the special behavior for Enter key safely.
600 // 613 //
601 // Now the last thing is to prevent the content of omnibox from being changed 614 // Now the last thing is to prevent the content of omnibox from being changed
602 // by GtkTextView when Tab or Enter key is pressed. Because we can't prevent 615 // by GtkTextView when Enter key is pressed. As OnBeforePossibleChange() and
603 // it, we use a backup and restore trick: If Enter is pressed, backup the 616 // OnAfterPossibleChange() will be called by GtkTextView before and after
604 // content of omnibox before sending the key event to |text_view_|, and 617 // changing the content, and the content is already saved in
605 // then restore it afterwards if IME did not handle the event. 618 // OnBeforePossibleChange(), so if the Enter key press event was not handled
619 // by IME, it's easy to restore the content in OnAfterPossibleChange(), as if
620 // it's not changed at all.
606 621
607 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget); 622 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget);
608 623
609 bool enter_pressed = (event->keyval == GDK_Return || 624 enter_was_pressed_ = (event->keyval == GDK_Return ||
610 event->keyval == GDK_ISO_Enter || 625 event->keyval == GDK_ISO_Enter ||
611 event->keyval == GDK_KP_Enter); 626 event->keyval == GDK_KP_Enter);
612 627
613 gchar* original_text = NULL;
614
615 // Enter key will have special behavior if it's not handled by IME.
616 // We need save the original content of |text_buffer_| and restore it when
617 // necessary, because GtkTextView might alter the content.
618 if (enter_pressed) {
619 GtkTextIter start, end;
620 gtk_text_buffer_get_bounds(text_buffer_, &start, &end);
621 original_text = gtk_text_buffer_get_text(text_buffer_, &start, &end, FALSE);
622 // Reset |char_inserted_|, which may be set in the "insert-text" signal
623 // handler, so that we'll know if an Enter key event was handled by IME.
624 char_inserted_ = 0;
625 }
626
627 // Set |tab_was_pressed_| to true if it's a Tab key press event, so that our 628 // Set |tab_was_pressed_| to true if it's a Tab key press event, so that our
628 // handler of "move-focus" signal can trigger Tab to search behavior when 629 // handler of "move-focus" signal can trigger Tab to search behavior when
629 // necessary. 630 // necessary.
630 tab_was_pressed_ = ((event->keyval == GDK_Tab || 631 tab_was_pressed_ = ((event->keyval == GDK_Tab ||
631 event->keyval == GDK_ISO_Left_Tab || 632 event->keyval == GDK_ISO_Left_Tab ||
632 event->keyval == GDK_KP_Tab) && 633 event->keyval == GDK_KP_Tab) &&
633 !(event->state & GDK_CONTROL_MASK)); 634 !(event->state & GDK_CONTROL_MASK));
634 635
636 // Reset |char_inserted_|, which may be set in the "insert-text" signal
637 // handler, so that we'll know if an Enter key event was handled by IME.
638 char_inserted_ = 0;
639
635 // Reset |paste_clipboard_requested_| to make sure we won't misinterpret this 640 // Reset |paste_clipboard_requested_| to make sure we won't misinterpret this
636 // key input action as a paste action. 641 // key input action as a paste action.
637 paste_clipboard_requested_ = false; 642 paste_clipboard_requested_ = false;
638 643
639 // Call the default handler, so that IME can work as normal. 644 // Call the default handler, so that IME can work as normal.
640 // New line characters will be filtered out by our "insert-text" 645 // New line characters will be filtered out by our "insert-text"
641 // signal handler attached to |text_buffer_| object. 646 // signal handler attached to |text_buffer_| object.
642 gboolean result = klass->key_press_event(widget, event); 647 gboolean result = klass->key_press_event(widget, event);
643 648
644 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can 649 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can
645 // only be triggered by pressing Tab key. 650 // only be triggered by pressing Tab key.
646 tab_was_pressed_ = false; 651 tab_was_pressed_ = false;
647 652
648 if (enter_pressed && (char_inserted_ == '\n' || char_inserted_ == '\r')) { 653 if (enter_was_pressed_ &&
654 (char_inserted_ == '\n' || char_inserted_ == '\r')) {
649 bool alt_held = (event->state & GDK_MOD1_MASK); 655 bool alt_held = (event->state & GDK_MOD1_MASK);
650 // Revert the original text in case the text has been changed.
651 // Call gtk_text_buffer_{begin|end}_user_action() to make sure |model_| will
652 // be updated correctly.
653 // Note: SetUserText() does not work here, it'll reset the keyword state.
654 DCHECK(original_text);
655 gtk_text_buffer_begin_user_action(text_buffer_);
656 gtk_text_buffer_set_text(text_buffer_, original_text, -1);
657 gtk_text_buffer_end_user_action(text_buffer_);
658 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); 656 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
659 result = TRUE; 657 result = TRUE;
660 } else if (!result && event->keyval == GDK_Escape && 658 } else if (!result && event->keyval == GDK_Escape &&
661 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) { 659 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) {
662 // We can handle the Escape key if |text_view_| did not handle it. 660 // We can handle the Escape key if |text_view_| did not handle it.
663 // If it's not handled by us, then we need to propagate it up to the parent 661 // If it's not handled by us, then we need to propagate it up to the parent
664 // widgets, so that Escape accelerator can still work. 662 // widgets, so that Escape accelerator can still work.
665 result = model_->OnEscapeKeyPressed(); 663 result = model_->OnEscapeKeyPressed();
666 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { 664 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) {
667 // Omnibox2 can switch its contents while pressing a control key. To switch 665 // Omnibox2 can switch its contents while pressing a control key. To switch
668 // the contents of omnibox2, we notify the AutocompleteEditModel class when 666 // the contents of omnibox2, we notify the AutocompleteEditModel class when
669 // the control-key state is changed. 667 // the control-key state is changed.
670 model_->OnControlKeyChanged(true); 668 model_->OnControlKeyChanged(true);
671 } 669 }
672 670
673 if (original_text) 671 // Set |enter_was_pressed_| to false, to make sure OnAfterPossibleChange() can
674 g_free(original_text); 672 // act as normal for changes made by other events.
673 enter_was_pressed_ = false;
675 674
676 // If the key event is not handled by |text_view_| or us, then we need to 675 // If the key event is not handled by |text_view_| or us, then we need to
677 // propagate the key event up to parent widgets by returning FALSE. 676 // propagate the key event up to parent widgets by returning FALSE.
678 // In this case we need to stop the signal emission explicitly to prevent the 677 // In this case we need to stop the signal emission explicitly to prevent the
679 // default "key-press-event" handler of |text_view_| from being called again. 678 // default "key-press-event" handler of |text_view_| from being called again.
680 if (!result) { 679 if (!result) {
681 static guint signal_id = 680 static guint signal_id =
682 g_signal_lookup("key-press-event", GTK_TYPE_WIDGET); 681 g_signal_lookup("key-press-event", GTK_TYPE_WIDGET);
683 g_signal_stop_emission(widget, signal_id, 0); 682 g_signal_stop_emission(widget, signal_id, 0);
684 } 683 }
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 const std::string& selected_text) { 1168 const std::string& selected_text) {
1170 GtkClipboard* clipboard = 1169 GtkClipboard* clipboard =
1171 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); 1170 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY);
1172 DCHECK(clipboard); 1171 DCHECK(clipboard);
1173 if (!clipboard) 1172 if (!clipboard)
1174 return; 1173 return;
1175 1174
1176 gtk_clipboard_set_text( 1175 gtk_clipboard_set_text(
1177 clipboard, selected_text.data(), selected_text.size()); 1176 clipboard, selected_text.data(), selected_text.size());
1178 } 1177 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698