From 3fc425dee9b9eb648b0ff14878129b9fd09a3f2c Mon Sep 17 00:00:00 2001 From: Jon Trowbridge Date: Fri, 23 Feb 2001 17:27:51 +0000 Subject: Fixed. (e_entry_select_region): Fixed. (e_entry_show_popup): Grab/ungrab 2001-02-23 Jon Trowbridge * gal/e-text/e-entry.c (e_entry_set_position): Fixed. (e_entry_select_region): Fixed. (e_entry_show_popup): Grab/ungrab the pointer and keyboard when the popup appears/disappears. This (mostly) solves the "floating popup" problem. (button_press_cb): Added. We catch button presses outside of the popup, and hide the popup when they occur. * gal/e-text/e-completion-view.c (e_completion_view_get_type, e_completion_view_class_init): Changed base class to GtkEventBox. (e_completion_view_key_press_handler): Make Escape always cause an unbrowse, even wehen we are editting. svn path=/trunk/; revision=8369 --- widgets/text/e-completion-view.c | 9 ++++++-- widgets/text/e-completion-view.h | 4 ++-- widgets/text/e-entry.c | 44 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/widgets/text/e-completion-view.c b/widgets/text/e-completion-view.c index 026cb151dd..407ff57459 100644 --- a/widgets/text/e-completion-view.c +++ b/widgets/text/e-completion-view.c @@ -83,7 +83,7 @@ e_completion_view_get_type (void) (GtkClassInitFunc) NULL }; - completion_view_type = gtk_type_unique (gtk_vbox_get_type (), &completion_view_info); + completion_view_type = gtk_type_unique (gtk_event_box_get_type (), &completion_view_info); } return completion_view_type; @@ -95,7 +95,7 @@ e_completion_view_class_init (ECompletionViewClass *klass) GtkObjectClass *object_class = (GtkObjectClass *) klass; GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - parent_class = GTK_OBJECT_CLASS (gtk_type_class (gtk_vbox_get_type ())); + parent_class = GTK_OBJECT_CLASS (gtk_type_class (gtk_event_box_get_type ())); e_completion_view_signals[E_COMPLETION_VIEW_NONEMPTY] = gtk_signal_new ("nonempty", @@ -348,6 +348,11 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin return FALSE; case GDK_Escape: + /* Unbrowse hack */ + cv->selection = -1; + dir = 0; + break; + case GDK_Left: /* Lynx-style "back" */ case GDK_KP_Left: if (cv->selection >= 0) { diff --git a/widgets/text/e-completion-view.h b/widgets/text/e-completion-view.h index 9b1baeb799..57268125c5 100644 --- a/widgets/text/e-completion-view.h +++ b/widgets/text/e-completion-view.h @@ -46,7 +46,7 @@ typedef struct _ECompletionView ECompletionView; typedef struct _ECompletionViewClass ECompletionViewClass; struct _ECompletionView { - GtkVBox parent; + GtkEventBox parent; ETableModel *model; GtkWidget *table; @@ -73,7 +73,7 @@ struct _ECompletionView { }; struct _ECompletionViewClass { - GtkVBoxClass parent_class; + GtkEventBoxClass parent_class; /* Signals */ void (*nonempty) (ECompletionView *cv); diff --git a/widgets/text/e-entry.c b/widgets/text/e-entry.c index e9ff4bedf5..07fddb6b87 100644 --- a/widgets/text/e-entry.c +++ b/widgets/text/e-entry.c @@ -357,17 +357,22 @@ e_entry_set_position (EEntry *entry, gint pos) else if (pos > e_text_model_get_text_length (entry->priv->item->model)) pos = e_text_model_get_text_length (entry->priv->item->model); - entry->priv->item->selection_start = pos; + entry->priv->item->selection_start = entry->priv->item->selection_end = pos; } void e_entry_select_region (EEntry *entry, gint pos1, gint pos2) { + gint len; + g_return_if_fail (entry != NULL && E_IS_ENTRY (entry)); + + len = e_text_model_get_text_length (entry->priv->item->model); + pos1 = CLAMP (pos1, 0, len); + pos2 = CLAMP (pos2, 0, len); - e_entry_set_position (entry, MAX (pos1, pos2)); - entry->priv->item->selection_end = entry->priv->item->selection_start; - e_entry_set_position (entry, MIN (pos1, pos2)); + entry->priv->item->selection_start = MIN (pos1, pos2); + entry->priv->item->selection_end = MAX (pos1, pos2); } /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ @@ -412,10 +417,16 @@ e_entry_show_popup (EEntry *entry, gboolean visible) e_completion_view_set_width (E_COMPLETION_VIEW (entry->priv->completion_view), dim->width); gtk_widget_show (pop); + gdk_keyboard_grab (GTK_WIDGET (entry)->window, TRUE, GDK_CURRENT_TIME); + gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE, + (GdkEventMask) GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, + NULL, NULL, GDK_CURRENT_TIME); } else { gtk_widget_hide (pop); + gdk_keyboard_ungrab (GDK_CURRENT_TIME); + gdk_pointer_ungrab (GDK_CURRENT_TIME); } @@ -572,6 +583,25 @@ e_entry_enable_completion (EEntry *entry, ECompletion *completion) e_entry_enable_completion_full (entry, completion, -1, NULL); } +static void +button_press_cb (GtkWidget *w, GdkEvent *ev, gpointer user_data) +{ + EEntry *entry = E_ENTRY (user_data); + GtkWidget *child; + + /* Bail out if our click happened inside of our widget. */ + child = gtk_get_event_widget (ev); + if (child != w) { + while (child) { + if (child == w) + return; + child = child->parent; + } + } + + e_entry_show_popup (entry, FALSE); +} + void e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint delay, EEntryCompletionHandler handler) { @@ -593,6 +623,11 @@ e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint del e_completion_view_set_complete_key (E_COMPLETION_VIEW (entry->priv->completion_view), GDK_Down); e_completion_view_set_uncomplete_key (E_COMPLETION_VIEW (entry->priv->completion_view), GDK_Up); + gtk_signal_connect_after (GTK_OBJECT (entry->priv->completion_view), + "button_press_event", + GTK_SIGNAL_FUNC (button_press_cb), + entry); + entry->priv->nonempty_signal_id = gtk_signal_connect (GTK_OBJECT (entry->priv->completion_view), "nonempty", GTK_SIGNAL_FUNC (nonempty_cb), @@ -624,6 +659,7 @@ e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint del entry); entry->priv->completion_view_popup = gtk_window_new (GTK_WINDOW_POPUP); + 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); -- cgit v1.2.3