diff options
author | Hans Breuer <hans@breuer.org> | 2009-07-17 14:26:02 +0200 |
---|---|---|
committer | Hans Breuer <hans@breuer.org> | 2009-07-17 17:26:48 +0200 |
commit | d0cf137ed910f83093da504fb7a40d0514fcd903 (patch) | |
tree | 43264ccde905f13ab23ae0cfc713280db917d596 | |
parent | d8d62ceb997af855c35e23855e9e9ef03775c9de (diff) | |
download | gdk-pixbuf-d0cf137ed910f83093da504fb7a40d0514fcd903.tar.gz |
More efficient version of _gdk_win32_window_queue_translation()
Don't create create an extraneous expose event for any scroll operation
that gtk+ does. Thanks to Alex for the hint.
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index d1d151c16..cf2708668 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -782,8 +782,8 @@ gdk_window_lookup (GdkNativeWindow hwnd) void _gdk_win32_window_destroy (GdkWindow *window, - gboolean recursing, - gboolean foreign_destroy) + gboolean recursing, + gboolean foreign_destroy) { GdkWindowObject *private = (GdkWindowObject *)window; GdkWindowImplWin32 *window_impl = GDK_WINDOW_IMPL_WIN32 (private->impl); @@ -3593,17 +3593,40 @@ _gdk_win32_window_queue_antiexpose (GdkWindow *window, return FALSE; } +/* + * queue_translation is meant to only move any outstanding invalid area + * in the given area by dx,dy. A typical example of when its needed is an + * app with two toplevels where one (A) overlaps the other (B). If the + * app first moves A so that B is invalidated and then scrolls B before + * handling the expose. The scroll operation will copy the invalid area + * to a new position, but when the invalid area is then exposed it only + * redraws the old areas not the place where the invalid data was copied + * by the scroll. + */ static void _gdk_win32_window_queue_translation (GdkWindow *window, GdkRegion *area, gint dx, gint dy) { - /* TODO: Get current updateregion, move any part of it that intersects area by dx,dy */ - HRGN hrgn = _gdk_win32_gdkregion_to_hrgn (area, dx, dy); - - API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), hrgn, TRUE)); - + HRGN hrgn = CreateRectRgn (0, 0, 0, 0); + int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE); + if (ret == ERROR) + WIN32_API_FAILED ("GetUpdateRgn"); + else if (ret != NULLREGION) + { + /* Get current updateregion, move any part of it that intersects area by dx,dy */ + HRGN update = _gdk_win32_gdkregion_to_hrgn (area, 0, 0); + ret = CombineRgn (update, hrgn, update, RGN_AND); + if (ret == ERROR) + WIN32_API_FAILED ("CombineRgn"); + else if (ret != NULLREGION) + { + OffsetRgn (update, dx, dy); + API_CALL (InvalidateRgn, (GDK_WINDOW_HWND (window), update, TRUE)); + } + DeleteObject (update); + } DeleteObject (hrgn); } |