diff options
author | Daniel van Vugt <daniel.van.vugt@canonical.com> | 2019-12-20 19:15:21 +0800 |
---|---|---|
committer | Robert Mader <robert.mader@posteo.de> | 2020-08-31 07:45:11 +0000 |
commit | 84512cb1f36633d32418720e3608d01c6122ee26 (patch) | |
tree | 245aafb987a2646967808ad4bcb789b4d5fdf80a | |
parent | 02a46f3708d3f518893aed8a9b49d86dc92e88ab (diff) | |
download | mutter-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.c | 54 |
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) |