]> source.dussan.org Git - tigervnc.git/commitdiff
Avoid clipboard updates when not focused 620/head
authorPierre Ossman <ossman@cendio.se>
Mon, 26 Mar 2018 12:17:04 +0000 (14:17 +0200)
committerPierre Ossman <ossman@cendio.se>
Mon, 26 Mar 2018 12:17:04 +0000 (14:17 +0200)
We don't want to surprise the user with unexpected clipboard changes
when vncviewer is in the background, and it is both wasteful and
possibly insecure to inform the server of every clipboard update
when the user isn't interacting with it.

vncviewer/Viewport.cxx
vncviewer/Viewport.h

index 3b56fce558d42d9be4bd70365e09c2779ba34897..6c10f3572f516e5cc8384a8cdf12b6b876dffe79 100644 (file)
@@ -118,6 +118,7 @@ Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
 #ifdef WIN32
     altGrArmed(false),
 #endif
+    pendingServerCutText(NULL), pendingClientCutText(NULL),
     menuCtrlKey(false), menuAltKey(false), cursor(NULL)
 {
 #if !defined(WIN32) && !defined(__APPLE__)
@@ -206,6 +207,8 @@ Viewport::~Viewport()
     delete cursor;
   }
 
+  clearPendingClipboard();
+
   // FLTK automatically deletes all child widgets, so we shouldn't touch
   // them ourselves here
 }
@@ -233,6 +236,8 @@ void Viewport::serverCutText(const char* str, rdr::U32 len)
   char *buffer;
   int size, ret;
 
+  clearPendingClipboard();
+
   if (!acceptClipboard)
     return;
 
@@ -249,6 +254,11 @@ void Viewport::serverCutText(const char* str, rdr::U32 len)
 
   vlog.debug("Got clipboard data (%d bytes)", (int)strlen(buffer));
 
+  if (!hasFocus()) {
+    pendingServerCutText = buffer;
+    return;
+  }
+
   // RFB doesn't have separate selection and clipboard concepts, so we
   // dump the data into both variants.
   if (setPrimary)
@@ -534,11 +544,18 @@ int Viewport::handle(int event)
   case FL_PASTE:
     buffer = new char[Fl::event_length() + 1];
 
+    clearPendingClipboard();
+
     // This is documented as to ASCII, but actually does to 8859-1
     ret = fl_utf8toa(Fl::event_text(), Fl::event_length(), buffer,
                      Fl::event_length() + 1);
     assert(ret < (Fl::event_length() + 1));
 
+    if (!hasFocus()) {
+      pendingClientCutText = buffer;
+      return 1;
+    }
+
     vlog.debug("Sending clipboard data (%d bytes)", (int)strlen(buffer));
 
     try {
@@ -598,6 +615,8 @@ int Viewport::handle(int event)
     Fl::disable_im();
 
     try {
+      flushPendingClipboard();
+
       // We may have gotten our lock keys out of sync with the server
       // whilst we didn't have focus. Try to sort this out.
       pushLEDState();
@@ -704,6 +723,33 @@ void Viewport::handleClipboardChange(int source, void *data)
 }
 
 
+void Viewport::clearPendingClipboard()
+{
+  delete [] pendingServerCutText;
+  pendingServerCutText = NULL;
+  delete [] pendingClientCutText;
+  pendingClientCutText = NULL;
+}
+
+
+void Viewport::flushPendingClipboard()
+{
+  if (pendingServerCutText) {
+    size_t len = strlen(pendingServerCutText);
+    if (setPrimary)
+      Fl::copy(pendingServerCutText, len, 0);
+    Fl::copy(pendingServerCutText, len, 1);
+  }
+  if (pendingClientCutText) {
+    size_t len = strlen(pendingClientCutText);
+    vlog.debug("Sending pending clipboard data (%d bytes)", (int)len);
+    cc->writer()->clientCutText(pendingClientCutText, len);
+  }
+
+  clearPendingClipboard();
+}
+
+
 void Viewport::handlePointerEvent(const rfb::Point& pos, int buttonMask)
 {
   if (!viewOnly) {
index 170be0d7b70da6f43ce1bd128867ef661d046747..7bfc418cb59f84710ce721983752e918e452b831 100644 (file)
@@ -70,6 +70,9 @@ private:
 
   static void handleClipboardChange(int source, void *data);
 
+  void clearPendingClipboard();
+  void flushPendingClipboard();
+
   void handlePointerEvent(const rfb::Point& pos, int buttonMask);
   static void handlePointerTimeout(void *data);
 
@@ -107,6 +110,9 @@ private:
   unsigned int altGrCtrlTime;
 #endif
 
+  const char* pendingServerCutText;
+  const char* pendingClientCutText;
+
   rdr::U32 menuKeySym;
   int menuKeyCode, menuKeyFLTK;
   Fl_Menu_Button *contextMenu;