From 1e304e6debd9045fbe2c7ba01865e7ea2dbff22b Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Tue, 12 Aug 2014 13:44:34 +0200 Subject: [PATCH] GtkSpinButton: Always emit value-changed when the adjustment is changed Changing adjustment via the property setter would not emit value-changed, however changing it via gtk_spin_button_configure would. This inconsistency had the following side-effects: - Setting an adjustment with a different value would not update the value shown by the spin button. - Creating a spin button like this (common in GtkBuilder XML) will not show the initial value: g_object_new (GTK_TYPE_SPIN_BUTTON, "adjustment", adj, NULL); Let's use the same code path (ie. gtk_spin_button_configure) for all public facing API for setting adjustment. The code that handled the details of swapping out the old adjustment with the new has been split into an unset_adjustment method and the rest has been folded into gtk_spin_button_configure. A spin button really needs an adjustment to work, so we don't need most of the NULL checks. However we do need to check in unset_adjustment because setting a new adjustment during object creation might try to unset a non-existent one. https://bugzilla.gnome.org/show_bug.cgi?id=734660 --- gtk/gtkspinbutton.c | 102 ++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c index 3348450729..f94b577ad1 100644 --- a/gtk/gtkspinbutton.c +++ b/gtk/gtkspinbutton.c @@ -268,6 +268,7 @@ static void gtk_spin_button_get_frame_size (GtkEntry *entry, gint *y, gint *width, gint *height); +static void gtk_spin_button_unset_adjustment (GtkSpinButton *spin_button); static void gtk_spin_button_set_orientation (GtkSpinButton *spin_button, GtkOrientation orientation); static void gtk_spin_button_snap (GtkSpinButton *spin_button, @@ -740,7 +741,7 @@ gtk_spin_button_finalize (GObject *object) GtkSpinButton *spin_button = GTK_SPIN_BUTTON (object); GtkSpinButtonPrivate *priv = spin_button->priv; - gtk_spin_button_set_adjustment (spin_button, NULL); + gtk_spin_button_unset_adjustment (spin_button); if (priv->down_panel_context) g_object_unref (priv->down_panel_context); @@ -1159,6 +1160,37 @@ gtk_spin_button_unrealize (GtkWidget *widget) } } +/* Callback used when the spin button's adjustment changes. + * We need to redraw the arrows when the adjustment’s range + * changes, and reevaluate our size request. + */ +static void +adjustment_changed_cb (GtkAdjustment *adjustment, gpointer data) +{ + GtkSpinButton *spin_button = GTK_SPIN_BUTTON (data); + GtkSpinButtonPrivate *priv = spin_button->priv; + + priv->timer_step = gtk_adjustment_get_step_increment (priv->adjustment); + gtk_widget_queue_resize (GTK_WIDGET (spin_button)); +} + +static void +gtk_spin_button_unset_adjustment (GtkSpinButton *spin_button) +{ + GtkSpinButtonPrivate *priv = spin_button->priv; + + if (priv->adjustment) + { + g_signal_handlers_disconnect_by_func (priv->adjustment, + gtk_spin_button_value_changed, + spin_button); + g_signal_handlers_disconnect_by_func (priv->adjustment, + adjustment_changed_cb, + spin_button); + g_clear_object (&priv->adjustment); + } +} + static void gtk_spin_button_set_orientation (GtkSpinButton *spin, GtkOrientation orientation) @@ -2106,12 +2138,28 @@ gtk_spin_button_configure (GtkSpinButton *spin_button, priv = spin_button->priv; - if (adjustment) - gtk_spin_button_set_adjustment (spin_button, adjustment); - else + if (!adjustment) adjustment = priv->adjustment; g_object_freeze_notify (G_OBJECT (spin_button)); + if (priv->adjustment != adjustment) + { + gtk_spin_button_unset_adjustment (spin_button); + + priv->adjustment = adjustment; + g_object_ref_sink (adjustment); + g_signal_connect (adjustment, "value-changed", + G_CALLBACK (gtk_spin_button_value_changed), + spin_button); + g_signal_connect (adjustment, "changed", + G_CALLBACK (adjustment_changed_cb), + spin_button); + priv->timer_step = gtk_adjustment_get_step_increment (priv->adjustment); + + g_object_notify (G_OBJECT (spin_button), "adjustment"); + gtk_widget_queue_resize (GTK_WIDGET (spin_button)); + } + if (priv->digits != digits) { priv->digits = digits; @@ -2206,20 +2254,6 @@ gtk_spin_button_new_with_range (gdouble min, return GTK_WIDGET (spin); } -/* Callback used when the spin button's adjustment changes. - * We need to redraw the arrows when the adjustment’s range - * changes, and reevaluate our size request. - */ -static void -adjustment_changed_cb (GtkAdjustment *adjustment, gpointer data) -{ - GtkSpinButton *spin_button = GTK_SPIN_BUTTON (data); - GtkSpinButtonPrivate *priv = spin_button->priv; - - priv->timer_step = gtk_adjustment_get_step_increment (priv->adjustment); - gtk_widget_queue_resize (GTK_WIDGET (spin_button)); -} - /** * gtk_spin_button_set_adjustment: * @spin_button: a #GtkSpinButton @@ -2237,34 +2271,10 @@ gtk_spin_button_set_adjustment (GtkSpinButton *spin_button, priv = spin_button->priv; - if (priv->adjustment != adjustment) - { - if (priv->adjustment) - { - g_signal_handlers_disconnect_by_func (priv->adjustment, - gtk_spin_button_value_changed, - spin_button); - g_signal_handlers_disconnect_by_func (priv->adjustment, - adjustment_changed_cb, - spin_button); - g_object_unref (priv->adjustment); - } - priv->adjustment = adjustment; - if (adjustment) - { - g_object_ref_sink (adjustment); - g_signal_connect (adjustment, "value-changed", - G_CALLBACK (gtk_spin_button_value_changed), - spin_button); - g_signal_connect (adjustment, "changed", - G_CALLBACK (adjustment_changed_cb), - spin_button); - priv->timer_step = gtk_adjustment_get_step_increment (priv->adjustment); - } - - g_object_notify (G_OBJECT (spin_button), "adjustment"); - gtk_widget_queue_resize (GTK_WIDGET (spin_button)); - } + gtk_spin_button_configure (spin_button, + adjustment, + priv->climb_rate, + priv->digits); } /**