summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete
diff options
context:
space:
mode:
authorsuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-30 22:36:21 +0000
committersuzhe@chromium.org <suzhe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-30 22:36:21 +0000
commitd1b67944b3d3bbe9f675f75ad5e55d898df5ffba (patch)
treead75489091064dafe999561a605bb15f54744938 /chrome/browser/autocomplete
parent19d94938db10c7ac39df17777163b39fbfea3ca3 (diff)
downloadchromium_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.cc44
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc27
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);
}
}