diff --git a/gtk/gtkdropdown.c b/gtk/gtkdropdown.c index 3441e67ea1..c47e35eae8 100644 --- a/gtk/gtkdropdown.c +++ b/gtk/gtkdropdown.c @@ -198,11 +198,9 @@ selection_changed (GtkSingleSelection *selection, { GtkDropDown *self = data; guint selected; - gpointer item; GtkFilter *filter; selected = gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (self->selection)); - item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection)); if (selected == GTK_INVALID_LIST_POSITION) { @@ -211,7 +209,14 @@ selection_changed (GtkSingleSelection *selection, else { gtk_stack_set_visible_child_name (GTK_STACK (self->button_stack), "item"); - gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (self->button_item), selected, item, FALSE); + } + + if (selected != gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (self->button_item))) + { + gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (self->button_item), + selected, + gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection)), + FALSE); } /* reset the filter so positions are 1-1 */ @@ -221,6 +226,26 @@ selection_changed (GtkSingleSelection *selection, gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (self->popup_selection), selected); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); +} + +static void +selection_item_changed (GtkSingleSelection *selection, + GParamSpec *pspec, + gpointer data) +{ + GtkDropDown *self = data; + gpointer item; + + item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection)); + + if (item != gtk_list_item_widget_get_item (GTK_LIST_ITEM_WIDGET (self->button_item))) + { + gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (self->button_item), + gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (self->selection)), + item, + FALSE); + } + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]); } @@ -289,7 +314,10 @@ gtk_drop_down_dispose (GObject *object) g_clear_object (&self->model); if (self->selection) - g_signal_handlers_disconnect_by_func (self->selection, selection_changed, self); + { + g_signal_handlers_disconnect_by_func (self->selection, selection_changed, self); + g_signal_handlers_disconnect_by_func (self->selection, selection_item_changed, self); + } g_clear_object (&self->filter_model); g_clear_pointer (&self->expression, gtk_expression_unref); g_clear_object (&self->selection); @@ -805,7 +833,10 @@ gtk_drop_down_set_model (GtkDropDown *self, gtk_list_view_set_model (GTK_LIST_VIEW (self->popup_list), NULL); if (self->selection) - g_signal_handlers_disconnect_by_func (self->selection, selection_changed, self); + { + g_signal_handlers_disconnect_by_func (self->selection, selection_changed, self); + g_signal_handlers_disconnect_by_func (self->selection, selection_item_changed, self); + } g_clear_object (&self->selection); g_clear_object (&self->filter_model); @@ -831,7 +862,9 @@ gtk_drop_down_set_model (GtkDropDown *self, g_object_unref (selection); g_signal_connect (self->selection, "notify::selected", G_CALLBACK (selection_changed), self); + g_signal_connect (self->selection, "notify::selected-item", G_CALLBACK (selection_item_changed), self); selection_changed (GTK_SINGLE_SELECTION (self->selection), NULL, self); + selection_item_changed (GTK_SINGLE_SELECTION (self->selection), NULL, self); } g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); diff --git a/gtk/gtksingleselection.c b/gtk/gtksingleselection.c index fb5c1ad435..7e06575872 100644 --- a/gtk/gtksingleselection.c +++ b/gtk/gtksingleselection.c @@ -200,7 +200,6 @@ gtk_single_selection_items_changed_cb (GListModel *model, { self->selected += added - removed; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]); } else { @@ -216,7 +215,6 @@ gtk_single_selection_items_changed_cb (GListModel *model, { self->selected = position + i; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]); } g_object_unref (item); @@ -226,6 +224,8 @@ gtk_single_selection_items_changed_cb (GListModel *model, } if (i == added) { + guint old_selected = self->selected; + /* the item really was deleted */ g_clear_object (&self->selected_item); if (self->autoselect) @@ -266,7 +266,9 @@ gtk_single_selection_items_changed_cb (GListModel *model, g_clear_object (&self->selected_item); self->selected = GTK_INVALID_LIST_POSITION; } - g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); + if (old_selected != self->selected) + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]); + /* the item was deleted above, so this is guaranteed to be new, even if the position didn't change */ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]); } }