Send lossless refresh even with pending updates

There might be parts of the screen that haven't changed and can
therefore be refreshed. Figure which parts these are and send just
those.
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index 3f92a42..126fb4e 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -965,18 +965,13 @@
 
 void VNCSConnectionST::writeDataUpdate()
 {
-  Region req;
+  Region req, pending;
   UpdateInfo ui;
   bool needNewUpdateInfo;
   const RenderedCursor *cursor;
 
   updates.enable_copyrect(cp.useCopyRect);
 
-  // See if we are allowed to send anything right now (the framebuffer
-  // might have changed in ways we haven't yet been informed of).
-  if (!server->checkUpdate())
-    return;
-
   // See what the client has requested (if anything)
   if (continuousUpdates)
     req = cuRegion.union_(requested);
@@ -986,6 +981,9 @@
   if (req.is_empty())
     return;
 
+  // Get any framebuffer changes we haven't yet been informed of
+  pending = server->getPendingRegion();
+
   // Get the lists of updates. Prior to exporting the data to the `ui' object,
   // getUpdateInfo() will normalize the `updates' object such way that its
   // `changed' and `copied' regions would not intersect.
@@ -1027,17 +1025,24 @@
     updateRenderedCursor = false;
   }
 
-  // Return if there is nothing to send the client.
-
-  if (updates.is_empty() && !writer()->needFakeUpdate() &&
-      !encodeManager.needsLosslessRefresh(req))
-    return;
-
   // The `updates' object could change, make sure we have valid update info.
 
   if (needNewUpdateInfo)
     updates.getUpdateInfo(&ui, req);
 
+  // If there are queued updates then we cannot safely send an update
+  // without risking a partially updated screen
+
+  if (!pending.is_empty()) {
+    // However we might still be able to send a lossless refresh
+    req.assign_subtract(pending);
+    req.assign_subtract(ui.changed);
+    req.assign_subtract(ui.copied);
+
+    ui.changed.clear();
+    ui.copied.clear();
+  }
+
   // Does the client need a server-side rendered cursor?
 
   cursor = NULL;
@@ -1059,6 +1064,8 @@
     damagedCursorRegion.assign_union(ui.changed.intersect(renderedCursorRect));
   }
 
+  // Return if there is nothing to send the client.
+
   if (ui.is_empty() && !writer()->needFakeUpdate() &&
       !encodeManager.needsLosslessRefresh(req))
     return;