mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
Make outstanding window moves work with the new model
We now copy outstanding window moves directly on the window and not to an intermediary pixmap, this means our previous code to combine window copies was wrong (it relied on each copy not destroying the source date). Furthermore, we can't just remove all the update area from the destination of the outstanding moves, as sometimes things get copied into that area and then used as the source of another copy. We replace the previous window copy combining with a naive version that just queues each move, just to get things right. Further work to optimize copies is possible. Also, we don't remove copy destinations that are used as source for later copies. We also clean up the memory management by not having move_region_on_impl taking ownership of the passed in region.
This commit is contained in:
parent
5ccc8b2ff1
commit
5742005aa1
@ -2219,10 +2219,25 @@ gdk_window_begin_paint_region (GdkWindow *window,
|
||||
gdk_region_union (implicit_paint->region, paint->region);
|
||||
|
||||
/* No need to do any moves that will end up over the exposed area */
|
||||
for (l = impl_window->outstanding_moves; l != NULL; l = l->next)
|
||||
if (impl_window->outstanding_moves)
|
||||
{
|
||||
move = l->data;
|
||||
gdk_region_subtract (move->region, paint->region);
|
||||
GdkRegion *remove;
|
||||
|
||||
remove = gdk_region_copy (paint->region);
|
||||
for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = l->prev)
|
||||
{
|
||||
move = l->data;
|
||||
/* Don't need this area */
|
||||
gdk_region_subtract (move->region, remove);
|
||||
|
||||
/* However if any of the destination we do need has a source
|
||||
in the updated region we do need that as a destination for
|
||||
the earlier moves */
|
||||
gdk_region_offset (move->region, -move->dx, -move->dy);
|
||||
gdk_region_subtract (remove, move->region);
|
||||
gdk_region_offset (move->region, move->dx, move->dy);
|
||||
}
|
||||
gdk_region_destroy (remove);
|
||||
}
|
||||
|
||||
/* Convert back to normal coords */
|
||||
@ -2521,79 +2536,33 @@ append_move_region (GdkWindowObject *impl_window,
|
||||
GdkRegion *region,
|
||||
int dx, int dy)
|
||||
{
|
||||
GList *moves_to_add, *l, *s;
|
||||
GdkRegion *intersection;
|
||||
GdkWindowRegionMove *move, *new_move, *existing_move;
|
||||
|
||||
GdkWindowRegionMove *move;
|
||||
|
||||
move = g_slice_new (GdkWindowRegionMove);
|
||||
move->region = region;
|
||||
move->region = gdk_region_copy (region);
|
||||
move->dx = dx;
|
||||
move->dy = dy;
|
||||
|
||||
moves_to_add = g_list_prepend (NULL, move);
|
||||
|
||||
for (l = impl_window->outstanding_moves; l != NULL; l = l->next)
|
||||
{
|
||||
existing_move = l->data;
|
||||
|
||||
for (s = moves_to_add; s != NULL; s = s->next)
|
||||
{
|
||||
move = s->data;
|
||||
|
||||
intersection = gdk_region_copy (move->region);
|
||||
gdk_region_offset (intersection, -move->dx, -move->dy);
|
||||
gdk_region_intersect (intersection, existing_move->region);
|
||||
gdk_region_offset (intersection, move->dx, move->dy);
|
||||
|
||||
if (!gdk_region_empty (intersection))
|
||||
{
|
||||
|
||||
new_move = g_slice_new (GdkWindowRegionMove);
|
||||
new_move->region = intersection;
|
||||
new_move->dx = move->dx + existing_move->dx;
|
||||
new_move->dy = move->dy + existing_move->dy;
|
||||
moves_to_add = g_list_prepend (moves_to_add, new_move);
|
||||
|
||||
gdk_region_subtract (move->region, intersection);
|
||||
gdk_region_subtract (existing_move->region, intersection);
|
||||
}
|
||||
else
|
||||
gdk_region_destroy (intersection);
|
||||
}
|
||||
}
|
||||
|
||||
impl_window->outstanding_moves = g_list_concat (impl_window->outstanding_moves,
|
||||
moves_to_add);
|
||||
|
||||
impl_window->outstanding_moves =
|
||||
g_list_prepend (impl_window->outstanding_moves, move);
|
||||
}
|
||||
|
||||
/* Moves bits and update area by dx/dy in impl window
|
||||
* Takes ownership of region.
|
||||
*/
|
||||
/* Moves bits and update area by dx/dy in impl window */
|
||||
static void
|
||||
move_region_on_impl (GdkWindowObject *private,
|
||||
GdkRegion *region, /* In impl window coords */
|
||||
int dx, int dy)
|
||||
{
|
||||
GdkWindowObject *impl_window;
|
||||
gboolean free_region;
|
||||
|
||||
if ((dx == 0 && dy == 0) ||
|
||||
gdk_region_empty (region))
|
||||
{
|
||||
gdk_region_destroy (region);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
free_region = TRUE;
|
||||
impl_window = gdk_window_get_impl_window (private);
|
||||
|
||||
if (1) /* Enable flicker free handling of moves. */
|
||||
{
|
||||
free_region = FALSE;
|
||||
|
||||
append_move_region (impl_window, region, dx, dy);
|
||||
}
|
||||
append_move_region (impl_window, region, dx, dy);
|
||||
else
|
||||
do_move_region_bits_on_impl (private,
|
||||
region, dx, dy);
|
||||
@ -2608,14 +2577,12 @@ move_region_on_impl (GdkWindowObject *private,
|
||||
gdk_region_offset (update_area, -dx, -dy);
|
||||
gdk_region_intersect (update_area, impl_window->update_area);
|
||||
gdk_region_subtract (impl_window->update_area, update_area);
|
||||
|
||||
/* Convert back */
|
||||
gdk_region_offset (update_area, dx, dy);
|
||||
gdk_region_union (impl_window->update_area, update_area);
|
||||
gdk_region_destroy (update_area);
|
||||
}
|
||||
|
||||
if (free_region)
|
||||
gdk_region_destroy (region);
|
||||
}
|
||||
|
||||
/* Flushes all outstanding changes to the window, call this
|
||||
@ -6221,7 +6188,7 @@ gdk_window_move_resize_internal (GdkWindow *window,
|
||||
/* convert from parent coords to impl */
|
||||
gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y);
|
||||
|
||||
move_region_on_impl (private, copy_area, dx, dy); /* Takes ownership of copy_area */
|
||||
move_region_on_impl (private, copy_area, dx, dy);
|
||||
|
||||
/* Invalidate affected part in the parent window
|
||||
* (no higher window should be affected)
|
||||
@ -6232,6 +6199,7 @@ gdk_window_move_resize_internal (GdkWindow *window,
|
||||
|
||||
gdk_region_destroy (old_region);
|
||||
gdk_region_destroy (new_region);
|
||||
gdk_region_destroy (copy_area);
|
||||
}
|
||||
|
||||
if (old_native_child_region)
|
||||
@ -6427,11 +6395,12 @@ gdk_window_scroll (GdkWindow *window,
|
||||
/* convert from window coords to impl */
|
||||
gdk_region_offset (copy_area, private->abs_x, private->abs_y);
|
||||
|
||||
move_region_on_impl (private, copy_area, dx, dy); /* Takes ownership of copy_area */
|
||||
move_region_on_impl (private, copy_area, dx, dy);
|
||||
|
||||
/* Invalidate not copied regions */
|
||||
gdk_window_invalidate_region (window, noncopy_area, TRUE);
|
||||
|
||||
gdk_region_destroy (copy_area);
|
||||
gdk_region_destroy (noncopy_area);
|
||||
|
||||
if (old_native_child_region)
|
||||
@ -6504,8 +6473,9 @@ gdk_window_move_region (GdkWindow *window,
|
||||
/* convert from window coords to impl */
|
||||
gdk_region_offset (copy_area, private->abs_x, private->abs_y);
|
||||
|
||||
move_region_on_impl (private, copy_area, dx, dy); /* Takes ownership of copy_area */
|
||||
move_region_on_impl (private, copy_area, dx, dy);
|
||||
|
||||
gdk_region_destroy (copy_area);
|
||||
gdk_region_destroy (source_area);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user