summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCosimo Cecchi <cosimo@endlessm.com>2018-11-20 18:25:51 -0800
committerCosimo Cecchi <cosimo.cecchi@gmail.com>2018-12-04 15:52:36 +0000
commit6743c18fdfa6dc48fb7d920640debe863018dd38 (patch)
tree24c9d7f4eeea560471c84513dfa7681d1753154e
parent4d649d6ee8a3a4e2d2805243a01d96d6a7ae3725 (diff)
downloadgnome-shell-6743c18fdfa6dc48fb7d920640debe863018dd38.tar.gz
StWidget: don't forget to invalidate the paint state if not on stage
If the actor is not on the stage yet (i.e. does not have a theme node), but has a paint state cached, we currently fail to invalidate it, which will lead to the actor painting with old contents once it gets onto the stage. This commit fixes the issue by changing our invalidation strategy; previously we were looking at the widget's own theme node to determine if it should be invalidated or not. Now we look at the theme nodes of our cached paint states. When the widget is mapped on stage, those are the same as the widget's own theme node, but when the widget is not on the stage, we'll still be able to invalidate them. As part of this, we move the invalidation API to StThemeNodePaintState, which is a more natural place for our use case. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/314
-rw-r--r--src/st/st-theme-node-drawing.c40
-rw-r--r--src/st/st-theme-node.h3
-rw-r--r--src/st/st-widget.c39
3 files changed, 49 insertions, 33 deletions
diff --git a/src/st/st-theme-node-drawing.c b/src/st/st-theme-node-drawing.c
index f59065aef..9f7e6b6ca 100644
--- a/src/st/st-theme-node-drawing.c
+++ b/src/st/st-theme-node-drawing.c
@@ -1414,6 +1414,32 @@ st_theme_node_load_background_image (StThemeNode *node)
return node->background_texture != COGL_INVALID_HANDLE;
}
+static gboolean
+st_theme_node_invalidate_resources_for_file (StThemeNode *node,
+ GFile *file)
+{
+ StBorderImage *border_image;
+ gboolean changed = FALSE;
+ GFile *theme_file;
+
+ theme_file = st_theme_node_get_background_image (node);
+ if ((theme_file != NULL) && g_file_equal (theme_file, file))
+ {
+ st_theme_node_invalidate_background_image (node);
+ changed = TRUE;
+ }
+
+ border_image = st_theme_node_get_border_image (node);
+ theme_file = border_image ? st_border_image_get_file (border_image) : NULL;
+ if ((theme_file != NULL) && g_file_equal (theme_file, file))
+ {
+ st_theme_node_invalidate_border_image (node);
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
static void st_theme_node_prerender_shadow (StThemeNodePaintState *state);
static void
@@ -2753,3 +2779,17 @@ st_theme_node_paint_state_invalidate (StThemeNodePaintState *state)
state->alloc_width = 0;
state->alloc_height = 0;
}
+
+gboolean
+st_theme_node_paint_state_invalidate_for_file (StThemeNodePaintState *state,
+ GFile *file)
+{
+ if (state->node != NULL &&
+ st_theme_node_invalidate_resources_for_file (state->node, file))
+ {
+ st_theme_node_paint_state_invalidate (state);
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/st/st-theme-node.h b/src/st/st-theme-node.h
index e71c1d522..1b43c9afe 100644
--- a/src/st/st-theme-node.h
+++ b/src/st/st-theme-node.h
@@ -291,6 +291,9 @@ void st_theme_node_paint_state_free (StThemeNodePaintState *state);
void st_theme_node_paint_state_copy (StThemeNodePaintState *state,
StThemeNodePaintState *other);
void st_theme_node_paint_state_invalidate (StThemeNodePaintState *state);
+gboolean st_theme_node_paint_state_invalidate_for_file (StThemeNodePaintState *state,
+ GFile *file);
+
void st_theme_node_paint_state_set_node (StThemeNodePaintState *state,
StThemeNode *node);
diff --git a/src/st/st-widget.c b/src/st/st-widget.c
index db984ac9b..7c39b3585 100644
--- a/src/st/st-widget.c
+++ b/src/st/st-widget.c
@@ -289,44 +289,17 @@ st_widget_texture_cache_changed (StTextureCache *cache,
{
StWidget *actor = ST_WIDGET (user_data);
StWidgetPrivate *priv = st_widget_get_instance_private (actor);
- StThemeNode *node = priv->theme_node;
- StBorderImage *border_image;
gboolean changed = FALSE;
- GFile *theme_file;
-
- if (node == NULL)
- return;
-
- theme_file = st_theme_node_get_background_image (node);
- if ((theme_file != NULL) && g_file_equal (theme_file, file))
- {
- st_theme_node_invalidate_background_image (node);
- changed = TRUE;
- }
+ int i;
- border_image = st_theme_node_get_border_image (node);
- theme_file = border_image ? st_border_image_get_file (border_image) : NULL;
- if ((theme_file != NULL) && g_file_equal (theme_file, file))
+ for (i = 0; i < G_N_ELEMENTS (priv->paint_states); i++)
{
- st_theme_node_invalidate_border_image (node);
- changed = TRUE;
+ StThemeNodePaintState *paint_state = &priv->paint_states[i];
+ changed |= st_theme_node_paint_state_invalidate_for_file (paint_state, file);
}
- if (changed)
- {
- /* If we prerender the background / border, we need to update
- * the paint state. We should probably implement a method to
- * the theme node to determine this, but for now, just wipe
- * the entire paint state.
- *
- * Use the existing state instead of a new one because it's
- * assumed the rest of the state will stay the same.
- */
- st_theme_node_paint_state_invalidate (current_paint_state (actor));
-
- if (clutter_actor_is_mapped (CLUTTER_ACTOR (actor)))
- clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
- }
+ if (changed && clutter_actor_is_mapped (CLUTTER_ACTOR (actor)))
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
}
static void