From: VMware, Inc <> Date: Wed, 20 Jul 2011 20:39:24 +0000 (-0700) Subject: Capture screen is not working well with CP enabled X-Git-Tag: 2011.07.19-450511~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=14cb1cc82ca3da1add76a81eb65c06f02eaa9cd0;p=thirdparty%2Fopen-vm-tools.git Capture screen is not working well with CP enabled The reason for the bug is that there is a race condition between regular copy/paste and guest screen capture copy/paste. 1. There is image A on host clipboard. 2. After switch from host to guest, image A is copied to guest clipboard 3. User does a guest screen capture and it is put into host clipboard 4. After switch from guest to host, image A is copied again from guest to host and overwrites the new guest screen capture in host clipboard. The fix is not to do step 3. To do this, clipboard timestamp after step 2 is recorded. When user switches from guest to host (step 4), the timestamp will be checked. If the timestamp is not changed, the guest clipboard will not be copied to host. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp index 4f3ad89ef..67d28903d 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp @@ -95,7 +95,8 @@ CopyPasteUIX11::CopyPasteUIX11() mBlockAdded(false), mBlockCtrl(0), mInited(false), - mTotalFileSize(0) + mTotalFileSize(0), + mGetTimestampOnly(false) { GuestDnDCPMgr *p = GuestDnDCPMgr::GetInstance(); ASSERT(p); @@ -263,6 +264,7 @@ CopyPasteUIX11::GetLocalClipboard(void) mClipTime = 0; mPrimTime = 0; mGHSelection = GDK_SELECTION_CLIPBOARD; + mGetTimestampOnly = false; g_debug("%s: retrieving timestamps\n", __FUNCTION__); refClipboard->request_contents(TARGET_NAME_TIMESTAMP, sigc::mem_fun(this, &CopyPasteUIX11::LocalClipboardTimestampCB)); @@ -630,6 +632,11 @@ CopyPasteUIX11::LocalPrimTimestampCB(const Gtk::SelectionData& sd) // IN g_debug("%s: Unable to get mPrimTime.", __FUNCTION__); } + if (mGetTimestampOnly) { + mLastTimestamp = mClipTime > mPrimTime ? mClipTime : mPrimTime; + return; + } + /* After got both timestamp, choose latest one as active selection. */ if (mClipTime > mPrimTime) { mGHSelection = GDK_SELECTION_CLIPBOARD; @@ -1190,6 +1197,18 @@ CopyPasteUIX11::GetRemoteClipboardCB(const CPClipboard *clip) // IN refClipboard->set_image(loader->get_pixbuf()); refPrimary->set_image(loader->get_pixbuf()); + + /* + * Record current clipboard timestamp to prevent unexpected clipboard + * exchange. + * + * XXX We should do this for all formats. + */ + mClipTime = 0; + mPrimTime = 0; + mGetTimestampOnly = true; + refClipboard->request_contents(TARGET_NAME_TIMESTAMP, + sigc::mem_fun(this, &CopyPasteUIX11::LocalClipboardTimestampCB)); } catch(...) { // Do nothing } diff --git a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h index c2bc12f25..a062f26ac 100644 --- a/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h +++ b/open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h @@ -120,6 +120,7 @@ private: DnDBlockControl *mBlockCtrl; bool mInited; uint64 mTotalFileSize; + bool mGetTimestampOnly; }; #endif // __COPYPASTE_UI_X11_H__