]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Capture screen is not working well with CP enabled
authorVMware, Inc <>
Wed, 20 Jul 2011 20:39:24 +0000 (13:39 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Wed, 20 Jul 2011 20:39:24 +0000 (13:39 -0700)
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 <mvanzin@vmware.com>
open-vm-tools/services/plugins/dndcp/copyPasteUIX11.cpp
open-vm-tools/services/plugins/dndcp/copyPasteUIX11.h

index 4f3ad89eff9ac74bf644268a7660c5e0ba66723f..67d28903deb5301fee231457c7702cf1463b274a 100644 (file)
@@ -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
       }
index c2bc12f2570c9bc7145f72884382b9c2c2465f0d..a062f26acea49825da06ae42c31d82f776febf01 100644 (file)
@@ -120,6 +120,7 @@ private:
    DnDBlockControl *mBlockCtrl;
    bool mInited;
    uint64 mTotalFileSize;
+   bool mGetTimestampOnly;
 };
 
 #endif // __COPYPASTE_UI_X11_H__