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

Unified Diff: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc

Issue 164142: Improve key event handling of AutocompleteEditViewGtk.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
===================================================================
--- chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc (revision 22995)
+++ chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc (working copy)
@@ -7,6 +7,8 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include <algorithm>
+
#include "app/gfx/font.h"
#include "app/l10n_util.h"
#include "base/gfx/gtk_util.h"
@@ -152,10 +154,13 @@
// The text view was floating. It will now be owned by the alignment.
gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view_);
- // TODO(deanm): This will probably have to be handled differently with the
- // tab to search business. Maybe we should just eat the tab characters.
- // We want the tab key to move focus, not insert a tab.
- gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), false);
+ // Allows inserting tab characters when pressing tab key, to prevent
+ // |text_view_| from moving focus.
+ // Tab characters will be filtered out by our "insert-text" signal handler
+ // attached to |text_buffer_| object.
+ // Tab key events will be handled by our "key-press-event" signal handler for
+ // tab to search feature.
+ gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), TRUE);
faded_text_tag_ = gtk_text_buffer_create_tag(text_buffer_,
NULL, "foreground", kTextBaseColor, NULL);
@@ -174,6 +179,8 @@
G_CALLBACK(&HandleBeginUserActionThunk), this);
g_signal_connect(text_buffer_, "end-user-action",
G_CALLBACK(&HandleEndUserActionThunk), this);
+ g_signal_connect(text_buffer_, "insert-text",
+ G_CALLBACK(&HandleInsertTextThunk), this);
// We connect to key press and release for special handling of a few keys.
g_signal_connect(text_view_, "key-press-event",
G_CALLBACK(&HandleKeyPressThunk), this);
@@ -202,6 +209,8 @@
text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetThunk), this);
g_signal_connect(text_view_, "drag-data-received",
G_CALLBACK(&HandleDragDataReceivedThunk), this);
+ g_signal_connect(text_view_, "backspace",
+ G_CALLBACK(&HandleBackSpaceThunk), this);
#if !defined(TOOLKIT_VIEWS)
registrar_.Add(this,
@@ -502,73 +511,41 @@
}
void AutocompleteEditViewGtk::HandleEndUserAction() {
- // Eat any newline / paragraphs that might have come in, for example in a
- // copy and paste. We want to make sure our widget stays single line.
- for (;;) {
- GtkTextIter cur;
- gtk_text_buffer_get_start_iter(text_buffer_, &cur);
-
- // If there is a line ending, this should put us right before the newline
- // or carriage return / newline (or Unicode) sequence. If not, we're done.
- if (gtk_text_iter_forward_to_line_end(&cur) == FALSE)
- break;
-
- // Stepping to the next cursor position should put us on the other side of
- // the newline / paragraph / etc sequence, and then delete this range.
- GtkTextIter next_line = cur;
- gtk_text_iter_forward_cursor_position(&next_line);
- gtk_text_buffer_delete(text_buffer_, &cur, &next_line);
-
- // We've invalidated our iterators, gotta start again.
- }
-
OnAfterPossibleChange();
}
gboolean AutocompleteEditViewGtk::HandleKeyPress(GtkWidget* widget,
GdkEventKey* event) {
- // This is very similar to the special casing of the return key in the
- // GtkTextView key_press default handler. TODO(deanm): We do however omit
- // some IME related code, this might become a problem if an IME wants to
- // handle enter. We can get at the im_context and do it ourselves if needed.
- if (event->keyval == GDK_Return ||
- event->keyval == GDK_ISO_Enter ||
- event->keyval == GDK_KP_Enter ||
- event->keyval == GDK_Tab ||
- (event->keyval == GDK_Escape &&
- (event->state & gtk_accelerator_get_default_mod_mask()) == 0)) {
- // Handle IME. This is basically taken from GtkTextView and reworked a bit.
- GtkTextIter iter;
- GtkTextView* text_view = GTK_TEXT_VIEW(text_view_);
- GtkTextMark* insert = gtk_text_buffer_get_insert(text_buffer_);
- gtk_text_buffer_get_iter_at_mark(text_buffer_, &iter, insert);
- gboolean can_insert = gtk_text_iter_can_insert(&iter, text_view->editable);
- if (gtk_im_context_filter_keypress(text_view->im_context, event)) {
- // The IME handled it, do the follow up IME handling.
- if (!can_insert) {
- gtk_im_context_reset(text_view->im_context);
- } else {
- text_view->need_im_reset = TRUE;
- }
+ GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget);
+
+ // Call the default handler, so that IME can work as normal.
+ // New line and tab characters will be filtered out by our "insert-text"
+ // signal handler attached to |text_buffer_| object.
+ klass->key_press_event(widget, event);
+
+ if ((event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab ||
+ event->keyval == GDK_KP_Tab) && !(event->state & GDK_CONTROL_MASK)) {
+ if (model_->is_keyword_hint() && !model_->keyword().empty()) {
+ model_->AcceptKeyword();
} else {
- // Ok, not handled by the IME, we can handle it.
- if (event->keyval == GDK_Tab) {
- if (model_->is_keyword_hint() && !model_->keyword().empty()) {
- model_->AcceptKeyword();
- } else {
- return FALSE; // Let GtkTextView handle the tab focus change.
- }
- } else if (event->keyval == GDK_Escape) {
- model_->OnEscapeKeyPressed();
- } else {
- bool alt_held = (event->state & GDK_MOD1_MASK);
- model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
- }
+ // Handle move focus by ourselves.
+ static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
+ g_signal_emit(widget, signal_id, 0, (event->state & GDK_SHIFT_MASK) ?
+ GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
}
- return TRUE; // Don't propagate into GtkTextView.
+ } else if (event->keyval == GDK_Return ||
+ event->keyval == GDK_ISO_Enter ||
+ event->keyval == GDK_KP_Enter) {
+ bool alt_held = (event->state & GDK_MOD1_MASK);
+ model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
+ } else if (event->keyval == GDK_Escape &&
+ (event->state & gtk_accelerator_get_default_mod_mask()) == 0) {
+ model_->OnEscapeKeyPressed();
}
- return FALSE; // Propagate into GtkTextView.
+ // Stop propagating the event to prevent the default handler from being
+ // called again.
+ return TRUE;
}
gboolean AutocompleteEditViewGtk::HandleKeyRelease(GtkWidget* widget,
@@ -646,9 +623,11 @@
else if (step != GTK_MOVEMENT_DISPLAY_LINES)
return; // Propagate into GtkTextView
model_->OnUpOrDownKeyPressed(move_amount);
+
// move-cursor doesn't use a signal accumulator on the return value (it
// just ignores then), so we have to stop the propagation.
- g_signal_stop_emission_by_name(text_view_, "move-cursor");
+ static guint signal_id = g_signal_lookup("move-cursor", GTK_TYPE_TEXT_VIEW);
+ g_signal_stop_emission(text_view_, signal_id, 0);
}
void AutocompleteEditViewGtk::HandleViewSizeRequest(GtkRequisition* req) {
@@ -762,10 +741,67 @@
if (model_->CanPasteAndGo(CollapseWhitespace(possible_url, true))) {
model_->PasteAndGo();
gtk_drag_finish(context, TRUE, TRUE, time);
- g_signal_stop_emission_by_name(text_view_, "drag-data-received");
+
+ static guint signal_id =
+ g_signal_lookup("drag-data-received", GTK_TYPE_WIDGET);
+ g_signal_stop_emission(text_view_, signal_id, 0);
}
}
+void AutocompleteEditViewGtk::HandleInsertText(
+ GtkTextBuffer* buffer, GtkTextIter* location, const gchar* text, gint len) {
+ std::string filtered_text;
+ filtered_text.reserve(len);
+
+ // Filter out new line and tab characters.
+ // |text| is guaranteed to be a valid UTF-8 string, so it's safe here to
+ // filter byte by byte.
+ for (gint i = 0; i < len; ++i) {
+ gchar c = text[i];
+ if (c == '\n' || c == '\r' || c == '\t')
+ continue;
+
+ filtered_text.push_back(c);
+ }
+
+ if (filtered_text.length()) {
+ // Call the default handler to insert filtered text.
+ GtkTextBufferClass* klass = GTK_TEXT_BUFFER_GET_CLASS(buffer);
+ klass->insert_text(buffer, location, filtered_text.data(),
+ static_cast<gint>(filtered_text.length()));
+ }
+
+ // Stop propagating the signal emission to prevent the default handler from
+ // being called again.
+ static guint signal_id = g_signal_lookup("insert-text", GTK_TYPE_TEXT_BUFFER);
+ g_signal_stop_emission(buffer, signal_id, 0);
+}
+
+void AutocompleteEditViewGtk::HandleBackSpace() {
+ // Checks if it's currently in keyword search mode.
+ if (model_->is_keyword_hint() || model_->keyword().empty())
+ return; // Propgate into GtkTextView.
+
+ GtkTextIter sel_start, sel_end;
+ // Checks if there is some text selected.
+ if (gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end))
+ return; // Propgate into GtkTextView.
+
+ GtkTextIter start;
+ gtk_text_buffer_get_start_iter(text_buffer_, &start);
+
+ if (!gtk_text_iter_equal(&start, &sel_start))
+ return; // Propgate into GtkTextView.
Dean McNamee 2009/08/12 15:17:55 I am missing why we look at the selection. Don't
James Su 2009/08/12 15:40:10 This piece of code just follows the logic of windo
+
+ // We're showing a keyword and the user pressed backspace at the beginning
+ // of the text. Delete the selected keyword.
+ model_->ClearKeyword(GetText());
+
+ // Stop propagating the signal emission into GtkTextView.
+ static guint signal_id = g_signal_lookup("backspace", GTK_TYPE_TEXT_VIEW);
+ g_signal_stop_emission(text_view_, signal_id, 0);
+}
+
void AutocompleteEditViewGtk::SelectAllInternal(bool reversed,
bool update_primary_selection) {
GtkTextIter start, end;
« 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