[gtk+/client-side-windows: 257/284] Make outstanding window moves work with the new model
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-windows: 257/284] Make outstanding window moves work with the new model
- Date: Thu, 2 Apr 2009 14:21:40 -0400 (EDT)
commit 5742005aa164bdd5cf9e5b05358085d6a8895ad7
Author: Alexander Larsson <alexl redhat com>
Date: Sat Feb 7 18:46:31 2009 +0100
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.
---
gdk/gdkwindow.c | 96 +++++++++++++++++++------------------------------------
1 files changed, 33 insertions(+), 63 deletions(-)
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5aeb9ef..d8ced4d 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -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);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]