forked from rpms/gnome-shell
157 lines
5.6 KiB
Diff
157 lines
5.6 KiB
Diff
From 6743c18fdfa6dc48fb7d920640debe863018dd38 Mon Sep 17 00:00:00 2001
|
|
From: Cosimo Cecchi <cosimo@endlessm.com>
|
|
Date: Tue, 20 Nov 2018 18:25:51 -0800
|
|
Subject: [PATCH 22/25] 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
|
|
---
|
|
src/st/st-theme-node-drawing.c | 40 ++++++++++++++++++++++++++++++++++
|
|
src/st/st-theme-node.h | 3 +++
|
|
src/st/st-widget.c | 39 +++++----------------------------
|
|
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
|
|
--
|
|
2.20.0
|
|
|