st/adjustment: Ensure changed signal emission is compressed
The docs say that `st_adjustment_set_values()` emits the `changed` signal only once but it's actually emitted for each changed property, this uses the `dispatch_properties_changed` vfunc to emit the `changed` signal only per call to `st_adjustment_set_values()`. As a positive side effect this also makes it possible to use `g_object_freeze/thaw_notify` to compress the `changed` signal emission when using the setters for properties. This also fixes the wrong emission of the `changed` signal in `st_adjustment_set_values()` when only the `value` property is changed. Side note: the code is heavily inspired by GtkAdjustment Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3023>
This commit is contained in:
parent
81f18d7ddb
commit
78eb5f2a68
@ -282,6 +282,34 @@ st_adjustment_dispose (GObject *object)
|
|||||||
G_OBJECT_CLASS (st_adjustment_parent_class)->dispose (object);
|
G_OBJECT_CLASS (st_adjustment_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
st_adjustment_dispatch_properties_changed (GObject *object,
|
||||||
|
guint n_pspecs,
|
||||||
|
GParamSpec **pspecs)
|
||||||
|
{
|
||||||
|
gboolean changed = FALSE;
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
G_OBJECT_CLASS (st_adjustment_parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs);
|
||||||
|
|
||||||
|
for (i = 0; i < n_pspecs; i++)
|
||||||
|
switch (pspecs[i]->param_id)
|
||||||
|
{
|
||||||
|
case PROP_LOWER:
|
||||||
|
case PROP_UPPER:
|
||||||
|
case PROP_STEP_INC:
|
||||||
|
case PROP_PAGE_INC:
|
||||||
|
case PROP_PAGE_SIZE:
|
||||||
|
changed = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
g_signal_emit (object, signals[CHANGED], 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
st_adjustment_class_init (StAdjustmentClass *klass)
|
st_adjustment_class_init (StAdjustmentClass *klass)
|
||||||
{
|
{
|
||||||
@ -291,6 +319,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
|
|||||||
object_class->get_property = st_adjustment_get_property;
|
object_class->get_property = st_adjustment_get_property;
|
||||||
object_class->set_property = st_adjustment_set_property;
|
object_class->set_property = st_adjustment_set_property;
|
||||||
object_class->dispose = st_adjustment_dispose;
|
object_class->dispose = st_adjustment_dispose;
|
||||||
|
object_class->dispatch_properties_changed = st_adjustment_dispatch_properties_changed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StAdjustment:actor:
|
* StAdjustment:actor:
|
||||||
@ -544,11 +573,11 @@ st_adjustment_clamp_page (StAdjustment *adjustment,
|
|||||||
* When setting multiple adjustment properties via their individual
|
* When setting multiple adjustment properties via their individual
|
||||||
* setters, multiple #GObject::notify and #StAdjustment::changed
|
* setters, multiple #GObject::notify and #StAdjustment::changed
|
||||||
* signals will be emitted. However, it’s possible to compress the
|
* signals will be emitted. However, it’s possible to compress the
|
||||||
* #GObject::notify signals into one by calling
|
* #GObject::notify and #StAdjustment::changed signals into one of each
|
||||||
* g_object_freeze_notify() and g_object_thaw_notify() around the
|
* by calling g_object_freeze_notify() and g_object_thaw_notify() around the
|
||||||
* calls to the individual setters.
|
* calls to the individual setters.
|
||||||
*
|
*
|
||||||
* Alternatively, using st_adjustment_set_values() will compress both
|
* Alternatively, st_adjustment_set_values() can be used to compress
|
||||||
* #GObject::notify and #StAdjustment::changed emissions.
|
* #GObject::notify and #StAdjustment::changed emissions.
|
||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -561,8 +590,6 @@ st_adjustment_set_lower (StAdjustment *adjustment,
|
|||||||
{
|
{
|
||||||
priv->lower = lower;
|
priv->lower = lower;
|
||||||
|
|
||||||
g_signal_emit (adjustment, signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_LOWER]);
|
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_LOWER]);
|
||||||
|
|
||||||
/* Defer clamp until after construction. */
|
/* Defer clamp until after construction. */
|
||||||
@ -600,8 +627,6 @@ st_adjustment_set_upper (StAdjustment *adjustment,
|
|||||||
{
|
{
|
||||||
priv->upper = upper;
|
priv->upper = upper;
|
||||||
|
|
||||||
g_signal_emit (adjustment, signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_UPPER]);
|
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_UPPER]);
|
||||||
|
|
||||||
/* Defer clamp until after construction. */
|
/* Defer clamp until after construction. */
|
||||||
@ -636,8 +661,6 @@ st_adjustment_set_step_increment (StAdjustment *adjustment,
|
|||||||
{
|
{
|
||||||
priv->step_increment = step;
|
priv->step_increment = step;
|
||||||
|
|
||||||
g_signal_emit (adjustment, signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_STEP_INC]);
|
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_STEP_INC]);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -668,8 +691,6 @@ st_adjustment_set_page_increment (StAdjustment *adjustment,
|
|||||||
{
|
{
|
||||||
priv->page_increment = page;
|
priv->page_increment = page;
|
||||||
|
|
||||||
g_signal_emit (adjustment, signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_INC]);
|
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_INC]);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -700,8 +721,6 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
|
|||||||
{
|
{
|
||||||
priv->page_size = size;
|
priv->page_size = size;
|
||||||
|
|
||||||
g_signal_emit (adjustment, signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_SIZE]);
|
g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_SIZE]);
|
||||||
|
|
||||||
/* We'll explicitly clamp after construction. */
|
/* We'll explicitly clamp after construction. */
|
||||||
@ -728,8 +747,8 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
|
|||||||
*
|
*
|
||||||
* Use this function to avoid multiple emissions of the #GObject::notify and
|
* Use this function to avoid multiple emissions of the #GObject::notify and
|
||||||
* #StAdjustment::changed signals. See st_adjustment_set_lower() for an
|
* #StAdjustment::changed signals. See st_adjustment_set_lower() for an
|
||||||
* alternative way of compressing multiple emissions of #GObject::notify into
|
* alternative way of compressing multiple emissions of #GObject::notify and
|
||||||
* one.
|
* #StAdjustmet::changed into one of each.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
st_adjustment_set_values (StAdjustment *adjustment,
|
st_adjustment_set_values (StAdjustment *adjustment,
|
||||||
@ -740,34 +759,19 @@ st_adjustment_set_values (StAdjustment *adjustment,
|
|||||||
gdouble page_increment,
|
gdouble page_increment,
|
||||||
gdouble page_size)
|
gdouble page_size)
|
||||||
{
|
{
|
||||||
StAdjustmentPrivate *priv;
|
|
||||||
gboolean emit_changed = FALSE;
|
|
||||||
|
|
||||||
g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
|
g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
|
||||||
g_return_if_fail (page_size >= 0 && page_size <= G_MAXDOUBLE);
|
g_return_if_fail (page_size >= 0 && page_size <= G_MAXDOUBLE);
|
||||||
g_return_if_fail (step_increment >= 0 && step_increment <= G_MAXDOUBLE);
|
g_return_if_fail (step_increment >= 0 && step_increment <= G_MAXDOUBLE);
|
||||||
g_return_if_fail (page_increment >= 0 && page_increment <= G_MAXDOUBLE);
|
g_return_if_fail (page_increment >= 0 && page_increment <= G_MAXDOUBLE);
|
||||||
|
|
||||||
priv = st_adjustment_get_instance_private (adjustment);
|
|
||||||
|
|
||||||
emit_changed = FALSE;
|
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (adjustment));
|
g_object_freeze_notify (G_OBJECT (adjustment));
|
||||||
|
|
||||||
emit_changed |= st_adjustment_set_lower (adjustment, lower);
|
st_adjustment_set_lower (adjustment, lower);
|
||||||
emit_changed |= st_adjustment_set_upper (adjustment, upper);
|
st_adjustment_set_upper (adjustment, upper);
|
||||||
emit_changed |= st_adjustment_set_step_increment (adjustment, step_increment);
|
st_adjustment_set_step_increment (adjustment, step_increment);
|
||||||
emit_changed |= st_adjustment_set_page_increment (adjustment, page_increment);
|
st_adjustment_set_page_increment (adjustment, page_increment);
|
||||||
emit_changed |= st_adjustment_set_page_size (adjustment, page_size);
|
st_adjustment_set_page_size (adjustment, page_size);
|
||||||
|
st_adjustment_set_value (adjustment, value);
|
||||||
if (value != priv->value)
|
|
||||||
{
|
|
||||||
st_adjustment_set_value (adjustment, value);
|
|
||||||
emit_changed = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (emit_changed)
|
|
||||||
g_signal_emit (G_OBJECT (adjustment), signals[CHANGED], 0);
|
|
||||||
|
|
||||||
g_object_thaw_notify (G_OBJECT (adjustment));
|
g_object_thaw_notify (G_OBJECT (adjustment));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user