diff options
author | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-30 22:36:21 +0000 |
---|---|---|
committer | suzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-30 22:36:21 +0000 |
commit | d1b67944b3d3bbe9f675f75ad5e55d898df5ffba (patch) | |
tree | ad75489091064dafe999561a605bb15f54744938 /chrome/browser/autocomplete | |
parent | 19d94938db10c7ac39df17777163b39fbfea3ca3 (diff) | |
download | chromium_src-d1b67944b3d3bbe9f675f75ad5e55d898df5ffba.zip chromium_src-d1b67944b3d3bbe9f675f75ad5e55d898df5ffba.tar.gz chromium_src-d1b67944b3d3bbe9f675f75ad5e55d898df5ffba.tar.bz2 |
[Linux] Omnibox: Avoid touching PRIMARY selection unexpectedly when moving cursor to the end.
BUG=63860
TEST=See bug report
Review URL: http://codereview.chromium.org/5309005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67773 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc | 44 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc | 27 |
2 files changed, 69 insertions, 2 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc index 17ddced..d4496b3 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_browsertest.cc @@ -33,6 +33,11 @@ #include "net/base/mock_host_resolver.h" #include "views/event.h" +#if defined(OS_LINUX) +#include <gdk/gdk.h> +#include <gtk/gtk.h> +#endif + using base::Time; using base::TimeDelta; @@ -94,6 +99,19 @@ const struct TestHistoryEntry { {"http://www.abc.com", "Page abc", kSearchText, 10000, 10000, true }, }; +#if defined(OS_LINUX) +// Returns the text stored in the PRIMARY clipboard. +std::string GetPrimarySelectionText() { + GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + DCHECK(clipboard); + + gchar* selection_text = gtk_clipboard_wait_for_text(clipboard); + std::string result(selection_text ? selection_text : ""); + g_free(selection_text); + return result; +} +#endif + } // namespace class AutocompleteEditViewTest : public InProcessBrowserTest, @@ -789,4 +807,30 @@ IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, UndoRedoLinux) { ASSERT_NO_FATAL_FAILURE(SendKey(app::VKEY_Z, true, false, false)); EXPECT_TRUE(edit_view->GetText().empty()); } + +// See http://crbug.com/63860 +IN_PROC_BROWSER_TEST_F(AutocompleteEditViewTest, PrimarySelection) { + browser()->FocusLocationBar(); + AutocompleteEditView* edit_view = NULL; + ASSERT_NO_FATAL_FAILURE(GetAutocompleteEditView(&edit_view)); + edit_view->SetUserText(L"Hello world"); + EXPECT_FALSE(edit_view->IsSelectAll()); + + // Move the cursor to the end. + ASSERT_NO_FATAL_FAILURE(SendKey(app::VKEY_END, false, false, false)); + + // Select all text by pressing Shift+Home + ASSERT_NO_FATAL_FAILURE(SendKey(app::VKEY_HOME, false, true, false)); + EXPECT_TRUE(edit_view->IsSelectAll()); + + // The selected content should be saved to the PRIMARY clipboard. + EXPECT_EQ("Hello world", GetPrimarySelectionText()); + + // Move the cursor to the end. + ASSERT_NO_FATAL_FAILURE(SendKey(app::VKEY_END, false, false, false)); + EXPECT_FALSE(edit_view->IsSelectAll()); + + // The content in the PRIMARY clipboard should not be cleared. + EXPECT_EQ("Hello world", GetPrimarySelectionText()); +} #endif diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc index 9f9e7f1..5bad09c 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc @@ -1808,21 +1808,44 @@ void AutocompleteEditViewGtk::HandleDeleteRange(GtkTextBuffer* buffer, void AutocompleteEditViewGtk::HandleMarkSetAlways(GtkTextBuffer* buffer, GtkTextIter* location, GtkTextMark* mark) { - if (mark == instant_mark_) + if (mark == instant_mark_ || !instant_mark_) return; GtkTextIter new_iter = *location; ValidateTextBufferIter(&new_iter); + static guint signal_id = g_signal_lookup("mark-set", GTK_TYPE_TEXT_BUFFER); + // "mark-set" signal is actually emitted after the mark's location is already // set, so if the location is beyond the instant anchor, we need to move the // mark again, which will emit the signal again. In order to prevent other // signal handlers from being called twice, we need to stop signal emission // before moving the mark again. if (gtk_text_iter_compare(&new_iter, location)) { - static guint signal_id = g_signal_lookup("mark-set", GTK_TYPE_TEXT_BUFFER); g_signal_stop_emission(buffer, signal_id, 0); gtk_text_buffer_move_mark(buffer, mark, &new_iter); + return; + } + + if (mark != gtk_text_buffer_get_insert(text_buffer_) && + mark != gtk_text_buffer_get_selection_bound(text_buffer_)) { + return; + } + + // See issue http://crbug.com/63860 + GtkTextIter insert; + GtkTextIter selection_bound; + gtk_text_buffer_get_iter_at_mark(buffer, &insert, + gtk_text_buffer_get_insert(buffer)); + gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound, + gtk_text_buffer_get_selection_bound(buffer)); + + GtkTextIter end; + gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); + + if (gtk_text_iter_compare(&insert, &end) > 0 || + gtk_text_iter_compare(&selection_bound, &end) > 0) { + g_signal_stop_emission(buffer, signal_id, 0); } } |