Try to render entire update in one go to avoid tearing.


git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3718 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/win/vncviewer/DesktopWindow.cxx b/win/vncviewer/DesktopWindow.cxx
index c85730a..744149d 100644
--- a/win/vncviewer/DesktopWindow.cxx
+++ b/win/vncviewer/DesktopWindow.cxx
@@ -42,6 +42,7 @@
 const int TIMER_BUMPSCROLL = 1;
 const int TIMER_POINTER_INTERVAL = 2;
 const int TIMER_POINTER_3BUTTON = 3;
+const int TIMER_UPDATE = 4;
 
 
 //
@@ -222,6 +223,10 @@
   bumpScrollTimer.setHWND(handle);
   bumpScrollTimer.setId(TIMER_BUMPSCROLL);
 
+  // Initialise the update timer
+  updateTimer.setHWND(handle);
+  updateTimer.setId(TIMER_UPDATE);
+
   // Hook the clipboard
   clipboard.setNotifier(this);
 
@@ -543,6 +548,9 @@
     case TIMER_POINTER_3BUTTON:
       ptr.handleTimer(callback, wParam);
       break;
+    case TIMER_UPDATE:
+      updateWindow();
+      break;
     }
     break;
 
@@ -871,6 +879,19 @@
 #endif
 }
 
+void DesktopWindow::updateWindow()
+{
+  Rect rect;
+
+  updateTimer.stop();
+
+  rect = damage.get_bounding_rect();
+  damage.clear();
+
+  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
+  InvalidateRect(frameHandle, &invalid, FALSE);
+}
+
 void
 DesktopWindow::hideLocalCursor() {
   // - Blit the cursor backing store over the cursor
@@ -901,6 +922,9 @@
     renderLocalCursor();
 
     invalidateDesktopRect(cursorBackingRect, false);
+    // Since we render the cursor onto the framebuffer, we need to update
+    // right away to get a responsive cursor.
+    updateWindow();
   }
 }
 
@@ -945,8 +969,9 @@
     rect = desktopToClient(buffer->calculateScaleBoundary(crect));
   } else rect = desktopToClient(crect);
   if (rect.intersect(client_size).is_empty()) return false;
-  RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y};
-  InvalidateRect(frameHandle, &invalid, FALSE);
+  damage.assign_union(rfb::Region(rect));
+  if (!updateTimer.isActive())
+    updateTimer.start(100);
   return true;
 }
 
@@ -1262,6 +1287,12 @@
 }
 
 
+void DesktopWindow::framebufferUpdateEnd()
+{
+  updateWindow();
+}
+
+
 void
 DesktopWindow::setName(const char* name) {
   if (name != desktopName) {