diff options
-rw-r--r-- | widgets/text/e-completion-test.c | 17 | ||||
-rw-r--r-- | widgets/text/e-completion-view.c | 6 | ||||
-rw-r--r-- | widgets/text/e-entry.c | 80 | ||||
-rw-r--r-- | widgets/text/e-text.c | 24 |
4 files changed, 98 insertions, 29 deletions
diff --git a/widgets/text/e-completion-test.c b/widgets/text/e-completion-test.c index 626842cb51..8550e9a10f 100644 --- a/widgets/text/e-completion-test.c +++ b/widgets/text/e-completion-test.c @@ -6,7 +6,7 @@ #include "e-completion.h" #include "e-entry.h" -#define TIMEOUT 50 +#define TIMEOUT 10 /* Dictionary Lookup test */ @@ -59,7 +59,7 @@ find_word (const gchar *str) a = m; else return m; - }; + } return b; } @@ -71,6 +71,7 @@ struct { gint current; gint len; gint limit; + gint count; } dict_info; static guint dict_tag = 0; @@ -88,15 +89,19 @@ dict_check (gpointer ptr) } i = dict_info.current; - while (limit > 0 && i < word_count && g_strncasecmp (dict_info.txt, word_array[i], dict_info.len) == 0) { + while (limit > 0 + && i < word_count + && dict_info.count < 50 + && g_strncasecmp (dict_info.txt, word_array[i], dict_info.len) == 0) { e_completion_found_match_full (dict_info.complete, word_array[i], dict_info.len / (double)strlen (word_array[i]), NULL, NULL); ++i; --limit; + ++dict_info.count; } dict_info.current = i; - dict_info.limit = MIN (dict_info.limit*2, 200); + dict_info.limit = MIN (dict_info.limit*2, 400); if (limit != 0) { dict_tag = 0; @@ -125,10 +130,10 @@ begin_dict_search (ECompletion *complete, const gchar *txt, gint pos, gint limit dict_info.start = -1; dict_info.current = -1; dict_info.len = len; - dict_info.limit = 20; + dict_info.limit = 100; + dict_info.count = 0; dict_tag = gtk_timeout_add (TIMEOUT, dict_check, NULL); } else { - g_message ("halting"); e_completion_end_search (complete); } } diff --git a/widgets/text/e-completion-view.c b/widgets/text/e-completion-view.c index 825e7c5e11..2ffb19f3e3 100644 --- a/widgets/text/e-completion-view.c +++ b/widgets/text/e-completion-view.c @@ -150,6 +150,7 @@ e_completion_view_class_init (ECompletionViewClass *klass) gtk_object_class_add_signals (object_class, e_completion_view_signals, E_COMPLETION_VIEW_LAST_SIGNAL); object_class->destroy = e_completion_view_destroy; + widget_class->key_press_event = e_completion_view_local_key_press_handler; } @@ -306,7 +307,7 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin ECompletionView *cv = E_COMPLETION_VIEW (user_data); gint dir = 0; gboolean key_handled = TRUE; - + /* Start up a completion.*/ if (cv->complete_key && key_event->keyval == cv->complete_key && !cv->editable) { gtk_signal_emit (GTK_OBJECT (cv), e_completion_view_signals[E_COMPLETION_VIEW_BROWSE], NULL); @@ -380,6 +381,7 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin gtk_signal_emit (GTK_OBJECT (cv), e_completion_view_signals[E_COMPLETION_VIEW_UNBROWSE]); stop_emission: + if (key_handled) gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "key_press_event"); @@ -518,6 +520,8 @@ e_completion_view_construct (ECompletionView *cv, ECompletion *completion) /* Make sure we don't call construct twice. */ g_return_if_fail (cv->completion == NULL); + GTK_WIDGET_SET_FLAGS (GTK_WIDGET (cv), GTK_CAN_FOCUS); + cv->completion = completion; gtk_object_ref (GTK_OBJECT (completion)); diff --git a/widgets/text/e-entry.c b/widgets/text/e-entry.c index 4ab21be725..b84e622de6 100644 --- a/widgets/text/e-entry.c +++ b/widgets/text/e-entry.c @@ -49,6 +49,12 @@ #include "e-text.h" #include "e-entry.h" +#define EVIL_POINTER_WARPING_HACK + +#ifdef EVIL_POINTER_WARPING_HACK +#include <gdk/gdkx.h> +#endif + #define MIN_ENTRY_WIDTH 150 #define INNER_BORDER 2 @@ -457,13 +463,13 @@ e_entry_show_popup (EEntry *entry, gboolean visible) if (visible) { GtkAllocation *dim = &(GTK_WIDGET (entry)->allocation); - gint x, y, fudge; + gint x, y, xo, yo, fudge; const GdkEventMask grab_mask = (GdkEventMask)GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK; /* Figure out where to put our popup. */ - gdk_window_get_origin (GTK_WIDGET (entry)->window, &x, &y); - x += dim->x; - y += dim->height + dim->y; + gdk_window_get_origin (GTK_WIDGET (entry)->window, &xo, &yo); + x = xo + dim->x; + y = yo + dim->height + dim->y; /* Put our popup slightly to the right and up, to try to give a visual cue that this popup is tied to this entry. Otherwise one-row popups can sort of "blend" with an entry @@ -475,16 +481,41 @@ e_entry_show_popup (EEntry *entry, gboolean visible) gtk_widget_set_uposition (pop, x, y); e_completion_view_set_width (E_COMPLETION_VIEW (entry->priv->completion_view), dim->width); +#ifdef EVIL_POINTER_WARPING_HACK + /* + I should have learned by now to listen to Havoc... + http://developer.gnome.org/doc/GGAD/faqs.html + */ + + if (! entry->priv->popup_is_visible) { + GdkWindow *gwin = GTK_WIDGET (entry)->window; + gint xx, yy; + gdk_window_get_pointer (gwin, &xx, &yy, NULL); + xx += xo; + yy += yo; + + /* If we are inside the "zone of death" where the popup will appear, warp the pointer to safety. + This is a horrible thing to do. */ + if (y <= yy && yy < yy + dim->height && x <= xx && xx < xx + dim->width) { + XWarpPointer (GDK_WINDOW_XDISPLAY (gwin), None, GDK_WINDOW_XWINDOW (gwin), + 0, 0, 0, 0, + xx - xo, (y-1) - yo); + } + } +#endif + gtk_widget_show (pop); if (! entry->priv->ptr_grab) { - entry->priv->ptr_grab = gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE, - grab_mask, NULL, NULL, GDK_CURRENT_TIME); - if (entry->priv->ptr_grab) - gtk_grab_add (GTK_WIDGET (entry->priv->completion_view)); + entry->priv->ptr_grab = (0 == gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE, + grab_mask, NULL, NULL, GDK_CURRENT_TIME)); + if (entry->priv->ptr_grab) { + gtk_grab_add (GTK_WIDGET (entry->priv->completion_view)); + } } - + + } else { gtk_widget_hide (pop); @@ -497,8 +528,6 @@ e_entry_show_popup (EEntry *entry, gboolean visible) entry->priv->ptr_grab = FALSE; entry->priv->last_completion_pos = -1; - - } e_completion_view_set_editable (E_COMPLETION_VIEW (entry->priv->completion_view), visible); @@ -668,6 +697,24 @@ button_press_cb (GtkWidget *w, GdkEvent *ev, gpointer user_data) unbrowse_cb (E_COMPLETION_VIEW (w), entry); } +static gint +key_press_cb (GtkWidget *w, GdkEventKey *ev, gpointer user_data) +{ + gint rv = 0; + /* Forward signal */ + gtk_signal_emit_by_name (GTK_OBJECT (user_data), "key_press_event", ev, &rv); + return rv; +} + +static gint +key_release_cb (GtkWidget *w, GdkEventKey *ev, gpointer user_data) +{ + gint rv = 0; + /* Forward signal */ + gtk_signal_emit_by_name (GTK_OBJECT (user_data), "key_release_event", ev, &rv); + return rv; +} + void e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint delay, EEntryCompletionHandler handler) { @@ -725,7 +772,16 @@ e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint del entry); entry->priv->completion_view_popup = gtk_window_new (GTK_WINDOW_POPUP); - + + gtk_signal_connect (GTK_OBJECT (entry->priv->completion_view_popup), + "key_press_event", + GTK_SIGNAL_FUNC (key_press_cb), + entry->canvas); + gtk_signal_connect (GTK_OBJECT (entry->priv->completion_view_popup), + "key_release_event", + GTK_SIGNAL_FUNC (key_release_cb), + entry->canvas); + gtk_object_ref (GTK_OBJECT (entry->priv->completion_view_popup)); gtk_object_sink (GTK_OBJECT (entry->priv->completion_view_popup)); gtk_window_set_policy (GTK_WINDOW (entry->priv->completion_view_popup), FALSE, TRUE, FALSE); diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index ceb09ab25d..e9b6e3272f 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -2471,12 +2471,10 @@ e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2 = *y1 + height; } -static void +static gboolean _get_xy_from_position (EText *text, gint position, gint *xp, gint *yp) { - if ( !text->lines ) - return; - if (xp || yp) { + if (text->lines && (xp || yp)) { struct line *lines = NULL; int x, y; double xd, yd; @@ -2506,7 +2504,11 @@ _get_xy_from_position (EText *text, gint position, gint *xp, gint *yp) *xp = x; if (yp) *yp = y; + + return TRUE; } + + return FALSE; } static gint @@ -3312,15 +3314,17 @@ _get_position(EText *text, ETextEventProcessorCommand *command) break; case E_TEP_FORWARD_LINE: - _get_xy_from_position(text, text->selection_end, &x, &y); - y += e_font_height (text->font); - new_pos = _get_position_from_xy(text, x, y); + if (_get_xy_from_position(text, text->selection_end, &x, &y)) { + y += e_font_height (text->font); + new_pos = _get_position_from_xy(text, x, y); + } break; case E_TEP_BACKWARD_LINE: - _get_xy_from_position(text, text->selection_end, &x, &y); - y -= e_font_height (text->font); - new_pos = _get_position_from_xy(text, x, y); + if (_get_xy_from_position(text, text->selection_end, &x, &y)) { + y -= e_font_height (text->font); + new_pos = _get_position_from_xy(text, x, y); + } break; case E_TEP_SELECT_WORD: |