summaryrefslogtreecommitdiffstats
path: root/views
diff options
context:
space:
mode:
authorsuzhe@google.com <suzhe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-28 00:53:35 +0000
committersuzhe@google.com <suzhe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-28 00:53:35 +0000
commit2f399395e09bbe0872a1fea9f9e3de7efdfaf1ed (patch)
tree36998fac7d445b572511276286cd3eec33828ecf /views
parentb4e6d2db0de191126e1542bc2db2ec292d68462c (diff)
downloadchromium_src-2f399395e09bbe0872a1fea9f9e3de7efdfaf1ed.zip
chromium_src-2f399395e09bbe0872a1fea9f9e3de7efdfaf1ed.tar.gz
chromium_src-2f399395e09bbe0872a1fea9f9e3de7efdfaf1ed.tar.bz2
Trigger find in page when pasting even if the text is not changed.
BUG=79002 TEST=See bug report. Review URL: http://codereview.chromium.org/6825034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views')
-rw-r--r--views/controls/textfield/native_textfield_gtk.cc130
-rw-r--r--views/controls/textfield/native_textfield_gtk.h46
-rw-r--r--views/controls/textfield/native_textfield_views.cc17
-rw-r--r--views/controls/textfield/native_textfield_views.h4
-rw-r--r--views/controls/textfield/native_textfield_win.cc6
5 files changed, 108 insertions, 95 deletions
diff --git a/views/controls/textfield/native_textfield_gtk.cc b/views/controls/textfield/native_textfield_gtk.cc
index 77b3940..dd0dc8f 100644
--- a/views/controls/textfield/native_textfield_gtk.cc
+++ b/views/controls/textfield/native_textfield_gtk.cc
@@ -32,7 +32,8 @@ const int kTextViewBorderWidth = 4;
// NativeTextfieldGtk, public:
NativeTextfieldGtk::NativeTextfieldGtk(Textfield* textfield)
- : textfield_(textfield) {
+ : textfield_(textfield),
+ paste_clipboard_requested_(false) {
if (textfield_->IsMultiLine() && textfield_->IsPassword())
NOTIMPLEMENTED(); // We don't support multiline password yet.
// Make |textfield| the focused view, so that when we get focused the focus
@@ -380,34 +381,10 @@ TextInputClient* NativeTextfieldGtk::GetTextInputClient() {
return NULL;
}
-// static
-gboolean NativeTextfieldGtk::OnKeyPressEventHandler(
- GtkWidget* widget,
- GdkEventKey* event,
- NativeTextfieldGtk* textfield) {
- return textfield->OnKeyPressEvent(event);
-}
-
-gboolean NativeTextfieldGtk::OnKeyPressEvent(GdkEventKey* event) {
- TextfieldController* controller = textfield_->GetController();
- if (controller) {
- KeyEvent key_event(reinterpret_cast<GdkEvent*>(event));
- return controller->HandleKeyEvent(textfield_, key_event);
- }
- return false;
-}
-
-// static
-gboolean NativeTextfieldGtk::OnActivateHandler(
- GtkWidget* widget,
- NativeTextfieldGtk* textfield) {
- return textfield->OnActivate();
-}
-
-gboolean NativeTextfieldGtk::OnActivate() {
+void NativeTextfieldGtk::OnActivate(GtkWidget* native_widget) {
GdkEvent* event = gtk_get_current_event();
if (!event || event->type != GDK_KEY_PRESS)
- return false;
+ return;
KeyEvent views_key_event(event);
gboolean handled = false;
@@ -420,51 +397,70 @@ gboolean NativeTextfieldGtk::OnActivate() {
if (!handled && widget)
handled = widget->HandleKeyboardEvent(views_key_event);
- return handled;
-}
-
-// static
-gboolean NativeTextfieldGtk::OnChangedHandler(
- GtkWidget* widget,
- NativeTextfieldGtk* textfield) {
- return textfield->OnChanged();
+ // Stop signal emission if the key event is handled by us.
+ if (handled) {
+ // Only GtkEntry has "activate" signal.
+ static guint signal_id = g_signal_lookup("activate", GTK_TYPE_ENTRY);
+ g_signal_stop_emission(native_widget, signal_id, 0);
+ }
}
-gboolean NativeTextfieldGtk::OnChanged() {
+void NativeTextfieldGtk::OnChanged(GObject* object) {
+ // We need to call TextfieldController::ContentsChanged() explicitly if the
+ // paste action didn't change the content at all. See http://crbug.com/79002
+ const bool call_contents_changed =
+ paste_clipboard_requested_ && GetText() == textfield_->text();
textfield_->SyncText();
textfield_->GetWidget()->NotifyAccessibilityEvent(
textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
- return false;
+ if (call_contents_changed) {
+ TextfieldController* controller = textfield_->GetController();
+ if (controller)
+ controller->ContentsChanged(textfield_, textfield_->text());
+ }
+ paste_clipboard_requested_ = false;
}
-// static
-gboolean NativeTextfieldGtk::OnMoveCursorHandler(
- GtkWidget* widget,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection,
- NativeTextfieldGtk* textfield) {
- return textfield->OnMoveCursor();
+gboolean NativeTextfieldGtk::OnButtonPressEvent(GtkWidget* widget,
+ GdkEventButton* event) {
+ paste_clipboard_requested_ = false;
+ return false;
}
-gboolean NativeTextfieldGtk::OnMoveCursor() {
+gboolean NativeTextfieldGtk::OnButtonReleaseEventAfter(GtkWidget* widget,
+ GdkEventButton* event) {
textfield_->GetWidget()->NotifyAccessibilityEvent(
textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
return false;
}
-// static
-gboolean NativeTextfieldGtk::OnMouseUpHandler(
- GtkWidget* widget,
- GdkEvent* event,
- NativeTextfieldGtk* textfield) {
- return textfield->OnMouseUp();
+gboolean NativeTextfieldGtk::OnKeyPressEvent(GtkWidget* widget,
+ GdkEventKey* event) {
+ paste_clipboard_requested_ = false;
+ return false;
+}
+
+gboolean NativeTextfieldGtk::OnKeyPressEventAfter(GtkWidget* widget,
+ GdkEventKey* event) {
+ TextfieldController* controller = textfield_->GetController();
+ if (controller) {
+ KeyEvent key_event(reinterpret_cast<GdkEvent*>(event));
+ return controller->HandleKeyEvent(textfield_, key_event);
+ }
+ return false;
}
-gboolean NativeTextfieldGtk::OnMouseUp() {
+void NativeTextfieldGtk::OnMoveCursor(GtkWidget* widget,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection) {
textfield_->GetWidget()->NotifyAccessibilityEvent(
textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
- return false;
+}
+
+void NativeTextfieldGtk::OnPasteClipboard(GtkWidget* widget) {
+ if (!textfield_->read_only())
+ paste_clipboard_requested_ = true;
}
////////////////////////////////////////////////////////////////////////////////
@@ -493,21 +489,25 @@ void NativeTextfieldGtk::NativeControlCreated(GtkWidget* widget) {
if (GTK_IS_TEXT_VIEW(widget)) {
GtkTextBuffer* text_buffer = gtk_text_view_get_buffer(
GTK_TEXT_VIEW(widget));
- g_signal_connect(text_buffer, "changed",
- G_CALLBACK(OnChangedHandler), this);
+ g_signal_connect(text_buffer, "changed", G_CALLBACK(OnChangedThunk), this);
} else {
- g_signal_connect(widget, "changed",
- G_CALLBACK(OnChangedHandler), this);
+ g_signal_connect(widget, "changed", G_CALLBACK(OnChangedThunk), this);
+ // In order to properly trigger Accelerators bound to VKEY_RETURN, we need
+ // to send an event when the widget gets the activate signal.
+ g_signal_connect(widget, "activate", G_CALLBACK(OnActivateThunk), this);
}
- g_signal_connect_after(widget, "move-cursor",
- G_CALLBACK(OnMoveCursorHandler), this);
+ g_signal_connect(widget, "move-cursor", G_CALLBACK(OnMoveCursorThunk), this);
+ g_signal_connect(widget, "button-press-event",
+ G_CALLBACK(OnButtonPressEventThunk), this);
+ g_signal_connect(widget, "key-press-event",
+ G_CALLBACK(OnKeyPressEventThunk), this);
+ g_signal_connect(widget, "paste-clipboard",
+ G_CALLBACK(OnPasteClipboardThunk), this);
+
g_signal_connect_after(widget, "button-release-event",
- G_CALLBACK(OnMouseUpHandler), this);
+ G_CALLBACK(OnButtonReleaseEventAfterThunk), this);
g_signal_connect_after(widget, "key-press-event",
- G_CALLBACK(OnKeyPressEventHandler), this);
- // In order to properly trigger Accelerators bound to VKEY_RETURN, we need to
- // send an event when the widget gets the activate signal.
- g_signal_connect(widget, "activate", G_CALLBACK(OnActivateHandler), this);
+ G_CALLBACK(OnKeyPressEventAfterThunk), this);
}
bool NativeTextfieldGtk::IsPassword() {
diff --git a/views/controls/textfield/native_textfield_gtk.h b/views/controls/textfield/native_textfield_gtk.h
index b28dd2e..0e7eb58 100644
--- a/views/controls/textfield/native_textfield_gtk.h
+++ b/views/controls/textfield/native_textfield_gtk.h
@@ -9,6 +9,7 @@
#include <gtk/gtk.h>
#include "base/string16.h"
+#include "ui/base/gtk/gtk_signal.h"
#include "views/controls/native_control_gtk.h"
#include "views/controls/textfield/native_textfield_wrapper.h"
@@ -65,34 +66,27 @@ class NativeTextfieldGtk : public NativeControlGtk,
bool IsPassword();
private:
+ // Gtk signal callbacks.
+ CHROMEGTK_CALLBACK_0(NativeTextfieldGtk, void, OnActivate);
+ CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnButtonPressEvent,
+ GdkEventButton*);
+ CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnButtonReleaseEventAfter,
+ GdkEventButton*);
+ CHROMEG_CALLBACK_0(NativeTextfieldGtk, void, OnChanged, GObject*);
+ CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnKeyPressEvent,
+ GdkEventKey*);
+ CHROMEGTK_CALLBACK_1(NativeTextfieldGtk, gboolean, OnKeyPressEventAfter,
+ GdkEventKey*);
+ CHROMEGTK_CALLBACK_3(NativeTextfieldGtk, void, OnMoveCursor,
+ GtkMovementStep, gint, gboolean);
+ CHROMEGTK_CALLBACK_0(NativeTextfieldGtk, void, OnPasteClipboard);
+
Textfield* textfield_;
- // Callback when the entry text changes.
- static gboolean OnKeyPressEventHandler(
- GtkWidget* entry,
- GdkEventKey* event,
- NativeTextfieldGtk* textfield);
- gboolean OnKeyPressEvent(GdkEventKey* event);
- static gboolean OnActivateHandler(
- GtkWidget* entry,
- NativeTextfieldGtk* textfield);
- gboolean OnActivate();
- static gboolean OnChangedHandler(
- GtkWidget* entry,
- NativeTextfieldGtk* textfield);
- gboolean OnChanged();
- static gboolean OnMoveCursorHandler(
- GtkWidget* entry,
- GtkMovementStep step,
- gint count,
- gboolean extend_selection,
- NativeTextfieldGtk* textfield);
- gboolean OnMoveCursor();
- static gboolean OnMouseUpHandler(
- GtkWidget* entry,
- GdkEvent* event,
- NativeTextfieldGtk* textfield);
- gboolean OnMouseUp();
+ // Indicates that user requested to paste clipboard.
+ // The actual paste clipboard action might be performed later if the
+ // clipboard is not empty.
+ bool paste_clipboard_requested_;
DISALLOW_COPY_AND_ASSIGN(NativeTextfieldGtk);
};
diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc
index 73b95f3..1f4f0d8 100644
--- a/views/controls/textfield/native_textfield_views.cc
+++ b/views/controls/textfield/native_textfield_views.cc
@@ -372,7 +372,7 @@ void NativeTextfieldViews::ExecuteCommand(int command_id) {
break;
case IDS_APP_PASTE:
if (editable)
- text_changed = model_->Paste();
+ text_changed = Paste();
break;
case IDS_APP_DELETE:
if (editable)
@@ -735,7 +735,7 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) {
break;
case ui::VKEY_V:
if (control && editable)
- cursor_changed = text_changed = model_->Paste();
+ cursor_changed = text_changed = Paste();
break;
case ui::VKEY_RIGHT:
control ? model_->MoveCursorToNextWord(selection)
@@ -939,6 +939,19 @@ void NativeTextfieldViews::OnAfterUserAction() {
controller->OnAfterUserAction(textfield_);
}
+bool NativeTextfieldViews::Paste() {
+ const bool success = model_->Paste();
+
+ // Calls TextfieldController::ContentsChanged() explicitly if the paste action
+ // did not change the content at all. See http://crbug.com/79002
+ if (success && model_->text() == textfield_->text()) {
+ TextfieldController* controller = textfield_->GetController();
+ if (controller)
+ controller->ContentsChanged(textfield_, textfield_->text());
+ }
+ return success;
+}
+
// static
bool NativeTextfieldViews::ShouldInsertChar(char16 ch, int flags) {
// Filter out all control characters, including tab and new line characters,
diff --git a/views/controls/textfield/native_textfield_views.h b/views/controls/textfield/native_textfield_views.h
index 532c8ec..1803e21 100644
--- a/views/controls/textfield/native_textfield_views.h
+++ b/views/controls/textfield/native_textfield_views.h
@@ -230,6 +230,10 @@ class NativeTextfieldViews : public views::View,
// Convenience method to call TextfieldController::OnAfterUserAction();
void OnAfterUserAction();
+ // Calls |model_->Paste()| and calls TextfieldController::ContentsChanged()
+ // explicitly if paste succeeded.
+ bool Paste();
+
// Checks if a char is ok to be inserted into the textfield. The |ch| is a
// modified character, i.e., modifiers took effect when generating this char.
static bool ShouldInsertChar(char16 ch, int flags);
diff --git a/views/controls/textfield/native_textfield_win.cc b/views/controls/textfield/native_textfield_win.cc
index a7e7443..9c4d196 100644
--- a/views/controls/textfield/native_textfield_win.cc
+++ b/views/controls/textfield/native_textfield_win.cc
@@ -907,8 +907,10 @@ void NativeTextfieldWin::OnPaste() {
std::wstring collapsed(CollapseWhitespace(clipboard_str, false));
if (textfield_->style() & Textfield::STYLE_LOWERCASE)
collapsed = l10n_util::ToLower(collapsed);
- // Force a Paste operation to trigger OnContentsChanged, even if identical
- // contents are pasted into the text box.
+ // Force a Paste operation to trigger ContentsChanged, even if identical
+ // contents are pasted into the text box. See http://crbug.com/79002
+ ReplaceSel(L"", false);
+ textfield_->SyncText();
text_before_change_.clear();
ReplaceSel(collapsed.c_str(), true);
}