]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Issue: Sometimes, there is a message "The system cannot find the file
authorOliver Kurth <okurth@vmware.com>
Fri, 2 Nov 2018 22:28:20 +0000 (15:28 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 2 Nov 2018 22:28:20 +0000 (15:28 -0700)
       specified" popped up when drag and drop over multiple remote apps.

Root cause:
When drag over multiple remote apps, multiple pairs of dragEnter and
dragLeave messages are sending. The DnD state or the dropSource/dataObject
are messed up when handling the 2nd DragEnter with the 1st DragLeave at
the same time.

Solution:
Besides fixing this issue, fixed several other issues also to enhance the
handling for multiple pairs of messages in the same time:
 1. In DnDController layer, avoid to reset the DnD state when handling the
    message responded from agent for previous sessions.
 2. In agent, only set the DnD state to be Ready when the previous
    DoDragDrop is really cancelled by OLE.
 3. In agent, only response to the button event when the drop is notified.
 4. In agent, add a 2s timeout checking for cancelling process to avoid
    conflicting with another DnDThread to create dropSrouce.
 5. In agent, add a 2s timeout checking for dragBegin process to avoid
    conflicting with previous dragBegin processing.
 6. Add virtual prefix to the method "GetData".

open-vm-tools/services/plugins/dndcp/dndGuest/vmGuestDnDMgr.cc
open-vm-tools/services/plugins/dndcp/dndGuest/vmGuestDnDMgr.hh
open-vm-tools/services/plugins/dndcp/dndGuestBase/guestDnD.hh
open-vm-tools/services/plugins/dndcp/dndGuestBase/guestDnDMgr.cc

index 9c5020a8324958d1bc3124aa07f7fbc3a70035dc..1a7f0ca9639f53e831106fca96127b52308ab09e 100644 (file)
@@ -26,6 +26,7 @@
 #include "dndRpcV4.hh"
 #include "tracer.hh"
 #include "vmGuestDnDMgr.hh"
+#include "vmGuestDnDSrc.hh"
 
 extern "C" {
 #include "debug.h"
@@ -122,3 +123,44 @@ VMGuestDnDMgr::CreateDnDRpcWithVersion(uint32 version)
       break;
    }
 }
+
+
+/**
+ * Got srcDragBegin from rpc with valid data. Create mSrc if the state machine
+ * is ready.
+ *
+ * @param[in] sessionId active DnD session id
+ * @param[in] capability controller capability
+ * @param[in] clip cross-platform clipboard data.
+ */
+
+void
+VMGuestDnDMgr::OnRpcSrcDragBegin(uint32 sessionId,
+                                 const CPClipboard *clip)
+{
+   TRACE_CALL();
+
+   if (!mDnDAllowed) {
+      g_debug("%s: DnD is not allowed.\n", __FUNCTION__);
+      return;
+   }
+
+   if (GUEST_DND_READY != mDnDState) {
+      g_debug("%s: Bad state: %d, reset\n", __FUNCTION__, mDnDState);
+      ResetDnD();
+      return;
+   }
+
+   if (mSrc) {
+      g_debug("%s: mSrc is not NULL\n", __FUNCTION__);
+      delete mSrc;
+      mSrc = NULL;
+   }
+
+   SetSessionId(sessionId);
+
+   ASSERT(clip);
+
+   mSrc = new VMGuestDnDSrc(this);
+   mSrc->OnRpcDragBegin(clip);
+}
index 76f828ed7d563ad565ff412d58f47dcf7e5acf21..36548cc01e55838927f9c7f042627d62c6d5c5cc 100644 (file)
@@ -43,6 +43,8 @@ protected:
    virtual void AddUnityDnDDetTimeoutEvent();
    virtual void AddHideDetWndTimerEvent();
    virtual void CreateDnDRpcWithVersion(uint32 version);
+   virtual void OnRpcSrcDragBegin(uint32 sessionId,
+                                  const CPClipboard *clip);
 
 private:
    ToolsAppCtx *mToolsAppCtx;
index bf8603915c3912f3328788d33540fe0c4309a29f..e452e72271b5c9d9917f2223a35c96fec908a7c5 100644 (file)
@@ -117,8 +117,8 @@ public:
    static gboolean DnDUnityDetTimeout(void *clientData);
 
 protected:
-   void OnRpcSrcDragBegin(uint32 sessionId,
-                          const CPClipboard *clip);
+   virtual void OnRpcSrcDragBegin(uint32 sessionId,
+                                  const CPClipboard *clip) = 0;
    void OnRpcQueryExiting(uint32 sessionId, int32 x, int32 y);
    void OnRpcUpdateUnityDetWnd(uint32 sessionId,
                                bool show,
@@ -163,7 +163,7 @@ protected:
    /* Callbacks from rpc for DnD source. */
    void OnRpcUpdateMouse(uint32 sessionId, int32 x, int32 y);
    void OnRpcDrop(uint32 sessionId, int32 x, int32 y);
-   void OnRpcCancel(uint32 sessionId);
+   virtual void OnRpcCancel(uint32 sessionId);
    void OnRpcGetFilesDone(uint32 sessionId,
                           bool success,
                           const uint8 *stagingDirCP,
index 832590cef06c9c6807296f8585f06afa9d97a73a..be4cb4e09823912137d4c821a20b5f7d236fc2b2 100644 (file)
 #include "guestDnD.hh"
 #include "guestDnDCPMgr.hh"
 
-#ifdef DND_VM
-#include "vmGuestDnDSrc.hh"
-#else
-#include "crtGuestDnDSrc.hh"
-#endif
-
 extern "C" {
    #include "debug.h"
 }
@@ -207,52 +201,6 @@ GuestDnDMgr::DestUIDragEnter(const CPClipboard *clip)
 }
 
 
-/**
- * Got srcDragBegin from rpc with valid data. Create mSrc if the state machine
- * is ready.
- *
- * @param[in] sessionId active DnD session id
- * @param[in] capability controller capability
- * @param[in] clip cross-platform clipboard data.
- */
-
-void
-GuestDnDMgr::OnRpcSrcDragBegin(uint32 sessionId,
-                               const CPClipboard *clip)
-{
-   TRACE_CALL();
-
-   if (!mDnDAllowed) {
-      g_debug("%s: DnD is not allowed.\n", __FUNCTION__);
-      return;
-   }
-
-   if  (GUEST_DND_READY != mDnDState) {
-      g_debug("%s: Bad state: %d, reset\n", __FUNCTION__, mDnDState);
-      ResetDnD();
-      return;
-   }
-
-   if (mSrc) {
-      g_debug("%s: mSrc is not NULL\n", __FUNCTION__);
-      delete mSrc;
-      mSrc = NULL;
-   }
-
-   SetSessionId(sessionId);
-
-   ASSERT(clip);
-
-#ifdef DND_VM
-   mSrc = new VMGuestDnDSrc(this);
-#else
-   mSrc = new CRTGuestDnDSrc(this);
-#endif
-
-   mSrc->OnRpcDragBegin(clip);
-}
-
-
 /**
  * Got queryExiting from rpc. Show the detection window on (x, y) to try to
  * detect any pending GH DnD.