st: Report correct paint volumes during transitions

StWidget reports a paint volume large enough to paint the current
theme node. As CSS transitions also paint the previous theme node,
the reported paint volume may be incorrect, resulting in screen
artifacts when painting outside the reported volume.

Add st_theme_node_transition_get_paint_box() to calculate an allocation
large enough to paint both theme nodes, and use it to report the correct
paint volume during transitions.

https://bugzilla.gnome.org/show_bug.cgi?id=640085
This commit is contained in:
Florian Müllner 2011-01-20 21:15:05 +01:00
parent 00ba937171
commit 289d577bc1
3 changed files with 33 additions and 9 deletions

View File

@ -182,6 +182,22 @@ st_theme_node_transition_update (StThemeNodeTransition *transition,
static void static void
calculate_offscreen_box (StThemeNodeTransition *transition, calculate_offscreen_box (StThemeNodeTransition *transition,
const ClutterActorBox *allocation) const ClutterActorBox *allocation)
{
ClutterActorBox paint_box;
st_theme_node_transition_get_paint_box (transition,
allocation,
&paint_box);
transition->priv->offscreen_box.x1 = paint_box.x1 - allocation->x1;
transition->priv->offscreen_box.y1 = paint_box.y1 - allocation->y1;
transition->priv->offscreen_box.x2 = paint_box.x2 - allocation->x1;
transition->priv->offscreen_box.y2 = paint_box.y2 - allocation->y1;
}
void
st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition,
const ClutterActorBox *allocation,
ClutterActorBox *paint_box)
{ {
StThemeNodeTransitionPrivate *priv = transition->priv; StThemeNodeTransitionPrivate *priv = transition->priv;
ClutterActorBox old_node_box, new_node_box; ClutterActorBox old_node_box, new_node_box;
@ -194,14 +210,10 @@ calculate_offscreen_box (StThemeNodeTransition *transition,
allocation, allocation,
&new_node_box); &new_node_box);
priv->offscreen_box.x1 = MIN (old_node_box.x1, new_node_box.x1) paint_box->x1 = MIN (old_node_box.x1, new_node_box.x1);
- allocation->x1; paint_box->y1 = MIN (old_node_box.y1, new_node_box.y1);
priv->offscreen_box.y1 = MIN (old_node_box.y1, new_node_box.y1) paint_box->x2 = MAX (old_node_box.x2, new_node_box.x2);
- allocation->y1; paint_box->y2 = MAX (old_node_box.y2, new_node_box.y2);
priv->offscreen_box.x2 = MAX (old_node_box.x2, new_node_box.x2)
- allocation->x1;
priv->offscreen_box.y2 = MAX (old_node_box.y2, new_node_box.y2)
- allocation->y1;
} }
static gboolean static gboolean

View File

@ -65,6 +65,10 @@ void st_theme_node_transition_paint (StThemeNodeTransition *transition,
ClutterActorBox *allocation, ClutterActorBox *allocation,
guint8 paint_opacity); guint8 paint_opacity);
void st_theme_node_transition_get_paint_box (StThemeNodeTransition *transition,
const ClutterActorBox *allocation,
ClutterActorBox *paint_box);
G_END_DECLS G_END_DECLS
#endif #endif

View File

@ -686,15 +686,23 @@ st_widget_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume)
{ {
ClutterActorBox paint_box, alloc_box; ClutterActorBox paint_box, alloc_box;
StThemeNode *theme_node; StThemeNode *theme_node;
StWidgetPrivate *priv;
ClutterVertex origin; ClutterVertex origin;
/* Setting the paint volume does not make sense when we don't have any allocation */ /* Setting the paint volume does not make sense when we don't have any allocation */
if (!clutter_actor_has_allocation (self)) if (!clutter_actor_has_allocation (self))
return FALSE; return FALSE;
priv = ST_WIDGET(self)->priv;
theme_node = st_widget_get_theme_node (ST_WIDGET(self)); theme_node = st_widget_get_theme_node (ST_WIDGET(self));
clutter_actor_get_allocation_box (self, &alloc_box); clutter_actor_get_allocation_box (self, &alloc_box);
st_theme_node_get_paint_box (theme_node, &alloc_box, &paint_box);
if (priv->transition_animation)
st_theme_node_transition_get_paint_box (priv->transition_animation,
&alloc_box, &paint_box);
else
st_theme_node_get_paint_box (theme_node, &alloc_box, &paint_box);
origin.x = paint_box.x1 - alloc_box.x1; origin.x = paint_box.x1 - alloc_box.x1;
origin.y = paint_box.y1 - alloc_box.y1; origin.y = paint_box.y1 - alloc_box.y1;