diff options
author | Owen Taylor <otaylor@redhat.com> | 2002-11-14 04:46:20 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2002-11-14 04:46:20 +0000 |
commit | a03f567e2fa6cee5cca419f03a967223aa8b131b (patch) | |
tree | 677c765e989d2f16aea66c7c0c3017846792d44a /gtk/gtkcombo.c | |
parent | 98aaac018d31c7e860969eaba7617a5113067645 (diff) | |
download | gtk+-a03f567e2fa6cee5cca419f03a967223aa8b131b.tar.gz |
Change so that updates of selection don't take effect immediately, but
Wed Nov 13 17:03:19 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkcombo.c: Change so that updates of selection
don't take effect immediately, but only when popdown
is closed with a button release within the combo
or Return/Enter.
* gtk/gtkcombo.c: Support Alt-Down to pop down the
combo, Alt-Up to pop it back up, Space to immediately
select current item.
* gtk/gtkcombo.c (gtk_combo_entry_key_press): Don't
move the focus when we get to the ends of the list
entries.
* gtk/gtkcombo.c: Fix handling of state in ad-hoc
keybinding handling to be a bit more reasonable.
* gtk/gtkcombo.c (gtk_combo_popup_list): Clear
last_focus_child when no item is selected so we
don't start focusing from some random place.
* gtk/gtkcombo.c (gtk_combo_init): Make
gtk_combo_set_use_arrows_always, enable_arrows_always
properties have no effect, they were an awful idea.
Always behave as if enable_arrows_always is true.
* gtk/gtknotebook.c: Fix a warning.
Diffstat (limited to 'gtk/gtkcombo.c')
-rw-r--r-- | gtk/gtkcombo.c | 129 |
1 files changed, 70 insertions, 59 deletions
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c index 701027a4c1..88004fb746 100644 --- a/gtk/gtkcombo.c +++ b/gtk/gtkcombo.c @@ -76,6 +76,8 @@ static void gtk_combo_get_pos (GtkCombo *combo, gint *height, gint *width); static void gtk_combo_popup_list (GtkCombo *combo); +static void gtk_combo_popdown_list (GtkCombo *combo); + static void gtk_combo_activate (GtkWidget *widget, GtkCombo *combo); static gboolean gtk_combo_popup_button_press (GtkWidget *button, @@ -84,8 +86,7 @@ static gboolean gtk_combo_popup_button_press (GtkWidget *button, static gboolean gtk_combo_popup_button_leave (GtkWidget *button, GdkEventCrossing *event, GtkCombo *combo); -static void gtk_combo_update_entry (GtkList *list, - GtkCombo *combo); +static void gtk_combo_update_entry (GtkCombo *combo); static void gtk_combo_update_list (GtkEntry *entry, GtkCombo *combo); static gint gtk_combo_button_press (GtkWidget *widget, @@ -145,7 +146,7 @@ gtk_combo_class_init (GtkComboClass * klass) PROP_ENABLE_ARROWS_ALWAYS, g_param_spec_boolean ("enable_arrows_always", _("Always enable arrows"), - _("Whether the arrow keys work, even if the entry contents are not in the list"), + _("Obsolete property, ignored"), TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (gobject_class, @@ -199,11 +200,11 @@ static int gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * combo) { GList *li; + guint state = event->state & gtk_accelerator_get_default_mod_mask (); /* completion */ - if ((event->keyval == GDK_Tab || - event->keyval == GDK_KP_Tab) && - (event->state & GDK_MOD1_MASK)) + if ((event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab) && + state == GDK_MOD1_MASK) { GtkEditable *editable = GTK_EDITABLE (entry); GCompletion * cmpl; @@ -214,8 +215,6 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com if ( !GTK_LIST (combo->list)->children ) return FALSE; - g_signal_stop_emission_by_name (entry, "key_press_event"); - cmpl = g_completion_new ((GCompletionFunc)gtk_combo_func); g_completion_add_items (cmpl, GTK_LIST (combo->list)->children); @@ -239,44 +238,49 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com return TRUE; } + if ((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && + state == GDK_MOD1_MASK) + { + gtk_combo_activate (NULL, combo); + return TRUE; + } + if (!combo->use_arrows || !GTK_LIST (combo->list)->children) return FALSE; + gtk_combo_update_list (GTK_ENTRY (combo->entry), combo); li = g_list_find (GTK_LIST (combo->list)->children, gtk_combo_find (combo)); - if ((event->keyval == GDK_Up) - || (event->keyval == GDK_KP_Up) - || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'p') || (event->keyval == 'P')))) + if (((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && state == 0) || + ((event->keyval == 'p' || event->keyval == 'P') && state == GDK_MOD1_MASK)) { - if (li) + if (!li) + li = g_list_last (GTK_LIST (combo->list)->children); + else li = li->prev; - if (!li && combo->use_arrows_always) - { - li = g_list_last (GTK_LIST (combo->list)->children); - } + if (li) { gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data)); - g_signal_stop_emission_by_name (entry, "key_press_event"); - return TRUE; + gtk_combo_update_entry (combo); } + + return TRUE; } - else if ((event->keyval == GDK_Down) - || (event->keyval == GDK_KP_Down) - || ((event->state & GDK_MOD1_MASK) && ((event->keyval == 'n') || (event->keyval == 'N')))) + if (((event->keyval == GDK_Down || event->keyval == GDK_KP_Down) && state == 0) || + ((event->keyval == 'n' || event->keyval == 'N') && state == GDK_MOD1_MASK)) { - if (li) + if (!li) + li = GTK_LIST (combo->list)->children; + else if (li) li = li->next; - if (!li && combo->use_arrows_always) - { - li = GTK_LIST (combo->list)->children; - } if (li) { gtk_list_select_child (GTK_LIST (combo->list), GTK_WIDGET (li->data)); - g_signal_stop_emission_by_name (entry, "key_press_event"); - return TRUE; + gtk_combo_update_entry (combo); } + + return TRUE; } return FALSE; } @@ -286,26 +290,28 @@ gtk_combo_window_key_press (GtkWidget *window, GdkEventKey *event, GtkCombo *combo) { - if (event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) + guint state = event->state & gtk_accelerator_get_default_mod_mask (); + + if ((event->keyval == GDK_Return || event->keyval == GDK_KP_Enter) && + state == 0) { - if (GTK_WIDGET_VISIBLE (combo->popwin)) - { - gtk_widget_hide (combo->popwin); - - if (GTK_WIDGET_HAS_GRAB (combo->popwin)) - { - gtk_grab_remove (combo->popwin); - gdk_display_pointer_ungrab (gtk_widget_get_display (window), - event->time); - gdk_display_keyboard_ungrab (gtk_widget_get_display (window), - event->time); - } - } + gtk_combo_popdown_list (combo); + gtk_combo_update_entry (combo); - g_signal_stop_emission_by_name (window, "key_press_event"); + return TRUE; + } + else if ((event->keyval == GDK_Up || event->keyval == GDK_KP_Up) && + state == GDK_MOD1_MASK) + { + gtk_combo_popdown_list (combo); return TRUE; } + else if ((event->keyval == GDK_space || event->keyval == GDK_KP_Space) && + state == 0) + { + gtk_combo_update_entry (combo); + } return FALSE; } @@ -538,6 +544,7 @@ gtk_combo_popup_list (GtkCombo * combo) { GTK_WIDGET_SET_FLAGS (list, GTK_CAN_FOCUS); gtk_widget_grab_focus (combo->list); + GTK_LIST (combo->list)->last_focus_child = NULL; GTK_WIDGET_UNSET_FLAGS (list, GTK_CAN_FOCUS); } @@ -604,7 +611,7 @@ gtk_combo_activate (GtkWidget *widget, return; gtk_combo_popup_list (combo); - + /* This must succeed since we already have the grab */ popup_grab_on_window (combo->popwin->window, gtk_get_current_event_time ()); @@ -657,12 +664,11 @@ gtk_combo_popup_button_leave (GtkWidget *button, } static void -gtk_combo_update_entry (GtkList * list, GtkCombo * combo) +gtk_combo_update_entry (GtkCombo * combo) { + GtkList *list = GTK_LIST (combo->list); char *text; - gtk_grab_remove (GTK_WIDGET (combo)); - g_signal_handler_block (list, combo->list_change_id); if (list->selection) { text = gtk_combo_func (GTK_LIST_ITEM (list->selection->data)); @@ -670,7 +676,6 @@ gtk_combo_update_entry (GtkList * list, GtkCombo * combo) text = ""; gtk_entry_set_text (GTK_ENTRY (combo->entry), text); } - g_signal_handler_unblock (list, combo->list_change_id); } static void @@ -720,6 +725,13 @@ gtk_combo_button_press (GtkWidget * widget, GdkEvent * event, GtkCombo * combo) return TRUE; } +static gboolean +is_within (GtkWidget *widget, + GtkWidget *ancestor) +{ + return widget == ancestor || gtk_widget_is_ancestor (widget, ancestor); +} + static void gtk_combo_button_event_after (GtkWidget *widget, GdkEvent *event, @@ -730,6 +742,8 @@ gtk_combo_button_event_after (GtkWidget *widget, if (event->type != GDK_BUTTON_RELEASE) return; + child = gtk_get_event_widget ((GdkEvent*) event); + if ((combo->current_button != 0) && (event->button.button == 1)) { /* This was the initial button press */ @@ -737,12 +751,7 @@ gtk_combo_button_event_after (GtkWidget *widget, combo->current_button = 0; /* Check to see if we released inside the button */ - child = gtk_get_event_widget ((GdkEvent*) event); - - while (child && child != (combo->button)) - child = child->parent; - - if (child == combo->button) + if (child && is_within (child, combo->button)) { gtk_grab_add (combo->popwin); gdk_pointer_grab (combo->popwin->window, TRUE, @@ -754,7 +763,11 @@ gtk_combo_button_event_after (GtkWidget *widget, } } + if (is_within (child, combo->list)) + gtk_combo_update_entry (combo); + gtk_combo_popdown_list (combo); + } static void @@ -837,7 +850,9 @@ gtk_combo_list_enter (GtkWidget *widget, static int gtk_combo_list_key_press (GtkWidget * widget, GdkEventKey * event, GtkCombo * combo) { - if (event->keyval == GDK_Escape) + guint state = event->state & gtk_accelerator_get_default_mod_mask (); + + if (event->keyval == GDK_Escape && state == 0) { if (GTK_WIDGET_HAS_GRAB (combo->list)) gtk_list_end_drag_selection (GTK_LIST (combo->list)); @@ -939,10 +954,6 @@ gtk_combo_init (GtkCombo * combo) gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (combo->popup))); gtk_widget_show (combo->list); - combo->list_change_id = g_signal_connect (combo->list, - "selection_changed", - G_CALLBACK (gtk_combo_update_entry), - combo); g_signal_connect (combo->popwin, "key_press_event", G_CALLBACK (gtk_combo_list_key_press), combo); g_signal_connect (combo->popwin, "button_press_event", |