summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel van Vugt <daniel.van.vugt@canonical.com>2019-12-20 19:15:21 +0800
committerRobert Mader <robert.mader@posteo.de>2020-08-31 07:45:11 +0000
commit84512cb1f36633d32418720e3608d01c6122ee26 (patch)
tree245aafb987a2646967808ad4bcb789b4d5fdf80a
parent02a46f3708d3f518893aed8a9b49d86dc92e88ab (diff)
downloadmutter-84512cb1f36633d32418720e3608d01c6122ee26.tar.gz
clutter/text: Check if attributes are equal before applying
Pango doesn't make it easy but the lists are generally extremely short and it's worth the effort. Because when they are equal we can avoid the `clutter_actor_queue_relayout` in `clutter_text_set_attributes`. This particularly avoids stuttering when moving the mouse over the gnome-shell calendar (which repeatedly sets `font-feature-settings: "tnum"` on `calendar-day-base` themed widgets). Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1411 https://gitlab.gnome.org/GNOME/mutter/merge_requests/983
-rw-r--r--clutter/clutter/clutter-text.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index e1947c437..caa689c94 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -5956,6 +5956,55 @@ clutter_text_get_line_wrap_mode (ClutterText *self)
return self->priv->wrap_mode;
}
+static gboolean
+attr_list_equal (PangoAttrList *old_attrs, PangoAttrList *new_attrs)
+{
+ PangoAttrIterator *i, *j;
+ gboolean equal = TRUE;
+
+ if (old_attrs == new_attrs)
+ return TRUE;
+
+ if (old_attrs == NULL || new_attrs == NULL)
+ return FALSE;
+
+ i = pango_attr_list_get_iterator (old_attrs);
+ j = pango_attr_list_get_iterator (new_attrs);
+
+ do
+ {
+ GSList *old_attributes, *new_attributes, *a, *b;
+
+ old_attributes = pango_attr_iterator_get_attrs (i);
+ new_attributes = pango_attr_iterator_get_attrs (j);
+
+ for (a = old_attributes, b = new_attributes;
+ a != NULL && b != NULL && equal;
+ a = a->next, b = b->next)
+ {
+ if (!pango_attribute_equal (a->data, b->data))
+ equal = FALSE;
+ }
+
+ if (a != NULL || b != NULL)
+ equal = FALSE;
+
+ g_slist_free_full (old_attributes,
+ (GDestroyNotify) pango_attribute_destroy);
+ g_slist_free_full (new_attributes,
+ (GDestroyNotify) pango_attribute_destroy);
+ }
+ while (equal && pango_attr_iterator_next (i) && pango_attr_iterator_next (j));
+
+ if (pango_attr_iterator_next (i) || pango_attr_iterator_next (j))
+ equal = FALSE;
+
+ pango_attr_iterator_destroy (i);
+ pango_attr_iterator_destroy (j);
+
+ return equal;
+}
+
/**
* clutter_text_set_attributes:
* @self: a #ClutterText
@@ -5979,10 +6028,7 @@ clutter_text_set_attributes (ClutterText *self,
priv = self->priv;
- /* While we should probably test for equality, Pango doesn't
- * provide us an easy method to check for AttrList equality.
- */
- if (priv->attrs == attrs)
+ if (attr_list_equal (priv->attrs, attrs))
return;
if (attrs)