From ea66a8a580ad496dc375ce6afeb2ee29f585a7fb Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 10 Apr 2013 14:25:26 +0200 Subject: [PATCH] win32: Report ScrollDC update region directly Rather than set the window update region and repaint this region when we get a WM_PAINT we just directly add it to the update region. No need to roundtrip via win32. This lets us also make sure we do this drawing in the same update cycle. This seems especially important on Win7, because ScrollDC seems to act kind of weird there, not using bitblt in areas where it seemingly could, which makes scrolling look really flashy. http://bugzilla.gnome.org/show_bug-cgi?id=674051 --- gdk/win32/gdkdrawable-win32.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c index b8a30b0c3d..14d9f45b76 100644 --- a/gdk/win32/gdkdrawable-win32.c +++ b/gdk/win32/gdkdrawable-win32.c @@ -1560,21 +1560,28 @@ blit_inside_drawable (HDC hdc, * scrolling a window that is partially obscured by another window. For * example, GIMP's toolbox being over the editor window. */ - RECT scrollRect, emptyRect; + RECT emptyRect, clipRect; HRGN updateRgn; + GdkRegion *update_region; - scrollRect.left = MIN (xsrc, xdest); - scrollRect.top = MIN (ysrc, ydest); - scrollRect.right = MAX (xsrc + width + 1, xdest + width + 1); - scrollRect.bottom = MAX (ysrc + height + 1, ydest + height + 1); + clipRect.left = xdest; + clipRect.top = ydest; + clipRect.right = xdest + width; + clipRect.bottom = ydest + height; SetRectEmpty (&emptyRect); updateRgn = CreateRectRgnIndirect (&emptyRect); - if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc, &scrollRect, NULL, updateRgn, NULL)) + if (!ScrollDC (hdc, xdest - xsrc, ydest - ysrc, NULL, &clipRect, updateRgn, NULL)) WIN32_GDI_FAILED ("ScrollDC"); - else if (!InvalidateRgn (src->handle, updateRgn, FALSE)) - WIN32_GDI_FAILED ("InvalidateRgn"); + else + { + GdkDrawable *wrapper = src->wrapper; + update_region = _gdk_win32_hrgn_to_region (updateRgn); + if (!gdk_region_empty (update_region)) + _gdk_window_invalidate_for_expose (GDK_WINDOW (wrapper), update_region); + gdk_region_destroy (update_region); + } if (!DeleteObject (updateRgn)) WIN32_GDI_FAILED ("DeleteObject");