From be6909b3c03f61dab35c491b2a9dea0ffd2e5658 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 26 Mar 2018 14:17:04 +0200 Subject: [PATCH] Avoid clipboard updates when not focused 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 | 46 ++++++++++++++++++++++++++++++++++++++++++ vncviewer/Viewport.h | 6 ++++++ 2 files changed, 52 insertions(+) diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index 3b56fce5..6c10f357 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -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) { diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h index 170be0d7..7bfc418c 100644 --- a/vncviewer/Viewport.h +++ b/vncviewer/Viewport.h @@ -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; -- 2.39.5