Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp	(revision 83631)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp	(revision 83632)
@@ -50,4 +50,7 @@
     /** Random 64-bit number embedded into szGuestOwnershipFlavor. */
     uint64_t                idGuestOwnership;
+    /** Ownership flavor CFStringRef returned by takePasteboardOwnership().
+     * This is the same a szGuestOwnershipFlavor only in core foundation terms. */
+    void                   *hStrOwnershipFlavor;
     /** The guest ownership flavor (type) string. */
     char                    szGuestOwnershipFlavor[64];
@@ -67,4 +70,6 @@
  * @returns IPRT status code (ignored).
  * @param   pCtx    The context.
+ *
+ * @note    Call must own lock.
  */
 static int vboxClipboardChanged(SHCLCONTEXT *pCtx)
@@ -73,8 +78,9 @@
         return VINF_SUCCESS;
 
+    /* Retrieve the formats currently in the clipboard and supported by vbox */
     uint32_t fFormats = 0;
-    bool fChanged = false;
-    /* Retrieve the formats currently in the clipboard and supported by vbox */
-    int rc = queryNewPasteboardFormats(pCtx->hPasteboard, &fFormats, &fChanged);
+    bool     fChanged = false;
+    int rc = queryNewPasteboardFormats(pCtx->hPasteboard, pCtx->idGuestOwnership, pCtx->hStrOwnershipFlavor,
+                                       &fFormats, &fChanged);
     if (   RT_SUCCESS(rc)
         && fChanged)
@@ -197,4 +203,5 @@
     LogFlowFunc(("fFormats=%02X\n", fFormats));
 
+    /** @todo r=bird: BUGBUG: The following is probably a mistake. */
     if (fFormats == VBOX_SHCL_FMT_NONE)
     {
@@ -226,5 +233,6 @@
     RTStrPrintf(szValue, sizeof(szValue), "%#x", fFormats);
 
-    takePasteboardOwnership(pCtx->hPasteboard, pCtx->idGuestOwnership, pCtx->szGuestOwnershipFlavor, szValue);
+    takePasteboardOwnership(pCtx->hPasteboard, pCtx->idGuestOwnership, pCtx->szGuestOwnershipFlavor, szValue,
+                            &pCtx->hStrOwnershipFlavor);
 
     ShClSvcUnlock();
Index: /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp	(revision 83631)
+++ /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp	(revision 83632)
@@ -75,15 +75,20 @@
  * that is supported by vbox and return it.
  *
- * @param   pPasteboard    Reference to the global pasteboard.
- * @param   pfFormats      Pointer for the bit combination of the
- *                         supported types.
- * @param   pfChanged      True if something has changed after the
- *                         last call.
- *
- * @returns IPRT status code. (Always VINF_SUCCESS atm.)
- */
-int queryNewPasteboardFormats(PasteboardRef pPasteboard, uint32_t *pfFormats, bool *pfChanged)
+ * @param   hPasteboard         Reference to the global pasteboard.
+ * @param   idOwnership         Our ownership ID.
+ * @param   hStrOwnershipFlavor The ownership flavor string reference returned
+ *                              by takePasteboardOwnership().
+ * @param   pfFormats           Pointer for the bit combination of the
+ *                              supported types.
+ * @param   pfChanged           True if something has changed after the
+ *                              last call.
+ *
+ * @returns VINF_SUCCESS.
+ */
+int queryNewPasteboardFormats(PasteboardRef hPasteboard, uint64_t idOwnership, void *hStrOwnershipFlavor,
+                              uint32_t *pfFormats, bool *pfChanged)
 {
-    OSStatus err = noErr;
+    OSStatus orc;
+
     *pfFormats = 0;
     *pfChanged = true;
@@ -91,5 +96,5 @@
     PasteboardSyncFlags syncFlags;
     /* Make sure all is in sync */
-    syncFlags = PasteboardSynchronize(pPasteboard);
+    syncFlags = PasteboardSynchronize(hPasteboard);
     /* If nothing changed return */
     if (!(syncFlags & kPasteboardModified))
@@ -101,47 +106,80 @@
 
     /* Are some items in the pasteboard? */
-    ItemCount itemCount;
-    err = PasteboardGetItemCount(pPasteboard, &itemCount);
-    if (itemCount < 1)
-    {
-        Log(("queryNewPasteboardFormats: changed: No items on the pasteboard\n"));
-        return VINF_SUCCESS;
-    }
-
-    /* The id of the first element in the pasteboard */
-    int rc = VINF_SUCCESS;
-    PasteboardItemID itemID;
-    if (!(err = PasteboardGetItemIdentifier(pPasteboard, 1, &itemID)))
-    {
-        /* Retrieve all flavors in the pasteboard, maybe there
-         * is something we can use. */
-        CFArrayRef flavorTypeArray;
-        if (!(err = PasteboardCopyItemFlavors(pPasteboard, itemID, &flavorTypeArray)))
-        {
-            CFIndex flavorCount;
-            flavorCount = CFArrayGetCount(flavorTypeArray);
-            for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
-            {
-                CFStringRef flavorType;
-                flavorType = static_cast <CFStringRef>(CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex));
-                /* Currently only unicode supported */
-                if (   UTTypeConformsTo(flavorType, kUTTypeUTF8PlainText)
-                    || UTTypeConformsTo(flavorType, kUTTypeUTF16PlainText))
-                {
-                    Log(("queryNewPasteboardFormats: Unicode flavor detected.\n"));
-                    *pfFormats |= VBOX_SHCL_FMT_UNICODETEXT;
-                }
-                else if (UTTypeConformsTo(flavorType, kUTTypeBMP))
-                {
-                    Log(("queryNewPasteboardFormats: BMP flavor detected.\n"));
-                    *pfFormats |= VBOX_SHCL_FMT_BITMAP;
-                }
-            }
-            CFRelease(flavorTypeArray);
-        }
-    }
-
-    Log(("queryNewPasteboardFormats: changed: *pfFormats=%#x\n", *pfFormats));
-    return rc;
+    ItemCount cItems = 0;
+    orc = PasteboardGetItemCount(hPasteboard, &cItems);
+    if (orc == 0)
+    {
+        if (cItems < 1)
+            Log(("queryNewPasteboardFormats: changed: No items on the pasteboard\n"));
+        else
+        {
+            /* The id of the first element in the pasteboard */
+            PasteboardItemID idItem = 0;
+            orc = PasteboardGetItemIdentifier(hPasteboard, 1, &idItem);
+            if (orc == 0)
+            {
+                /*
+                 * Retrieve all flavors on the pasteboard, maybe there
+                 * is something we can use.  Or maybe we're the owner.
+                 */
+                CFArrayRef hFlavors = 0;
+                orc = PasteboardCopyItemFlavors(hPasteboard, idItem, &hFlavors);
+                if (orc == 0)
+                {
+                    CFIndex cFlavors = CFArrayGetCount(hFlavors);
+                    for (CFIndex idxFlavor = 0; idxFlavor < cFlavors; idxFlavor++)
+                    {
+                        CFStringRef hStrFlavor = (CFStringRef)CFArrayGetValueAtIndex(hFlavors, idxFlavor);
+                        if (   idItem == (PasteboardItemID)idOwnership
+                            && hStrOwnershipFlavor
+                            && CFStringCompare(hStrFlavor, (CFStringRef)hStrOwnershipFlavor, 0) == kCFCompareEqualTo)
+                        {
+                            /* We made the changes ourselves. */
+                            Log2(("queryNewPasteboardFormats: no-changed: our clipboard!\n"));
+                            *pfChanged = false;
+                            *pfFormats = 0;
+                            break;
+                        }
+
+                        if (UTTypeConformsTo(hStrFlavor, kUTTypeBMP))
+                        {
+                            Log(("queryNewPasteboardFormats: BMP flavor detected.\n"));
+                            *pfFormats |= VBOX_SHCL_FMT_BITMAP;
+                        }
+                        else if (   UTTypeConformsTo(hStrFlavor, kUTTypeUTF8PlainText)
+                                 || UTTypeConformsTo(hStrFlavor, kUTTypeUTF16PlainText))
+                        {
+                            Log(("queryNewPasteboardFormats: Unicode flavor detected.\n"));
+                            *pfFormats |= VBOX_SHCL_FMT_UNICODETEXT;
+                        }
+#ifdef LOG_ENABLED
+                        else if (LogIs2Enabled())
+                        {
+                            if (CFStringGetCharactersPtr(hStrFlavor))
+                                Log2(("queryNewPasteboardFormats: Unknown flavor: %ls.\n", CFStringGetCharactersPtr(hStrFlavor)));
+                            else if (CFStringGetCStringPtr(hStrFlavor, kCFStringEncodingUTF8))
+                                Log2(("queryNewPasteboardFormats: Unknown flavor: %s.\n",
+                                      CFStringGetCStringPtr(hStrFlavor, kCFStringEncodingUTF8)));
+                            else
+                                Log2(("queryNewPasteboardFormats: Unknown flavor: ???\n"));
+                        }
+#endif
+                    }
+
+                    CFRelease(hFlavors);
+                }
+                else
+                    Log(("queryNewPasteboardFormats: PasteboardCopyItemFlavors failed - %d (%#x)\n", orc, orc));
+            }
+            else
+                Log(("queryNewPasteboardFormats: PasteboardGetItemIdentifier failed - %d (%#x)\n", orc, orc));
+
+            if (*pfChanged)
+                Log(("queryNewPasteboardFormats: changed: *pfFormats=%#x\n", *pfFormats));
+        }
+    }
+    else
+        Log(("queryNewPasteboardFormats: PasteboardGetItemCount failed - %d (%#x)\n", orc, orc));
+    return VINF_SUCCESS;
 }
 
@@ -289,8 +327,12 @@
  *
  * @returns VBox status code.
- * @param   hPasteboard         The pastboard handle (reference).
- * @param   idOwnership         The ownership ID to use now.
- * @param   pszOwnershipFlavor  The ownership indicator flavor
- * @param   pszOwnershipValue   The ownership value (stringified format mask).
+ * @param   hPasteboard             The pastboard handle (reference).
+ * @param   idOwnership             The ownership ID to use now.
+ * @param   pszOwnershipFlavor      The ownership indicator flavor
+ * @param   pszOwnershipValue       The ownership value (stringified format mask).
+ * @param   phStrOwnershipFlavor    Pointer to a CFStringRef variable holding
+ *                                  the current ownership flavor string.  This
+ *                                  will always be released, and set again on
+ *                                  success.
  *
  * @todo    Add fFormats so we can make promises about available formats at once
@@ -298,7 +340,17 @@
  *          flavor priority.
  */
-int takePasteboardOwnership(PasteboardRef hPasteboard, uint64_t idOwnership,
-                            const char *pszOwnershipFlavor, const char *pszOwnershipValue)
+int takePasteboardOwnership(PasteboardRef hPasteboard, uint64_t idOwnership, const char *pszOwnershipFlavor,
+                            const char *pszOwnershipValue, void **phStrOwnershipFlavor)
 {
+    /*
+     * Release the old string.
+     */
+    if (*phStrOwnershipFlavor)
+    {
+        CFStringRef hOldFlavor = (CFStringRef)*phStrOwnershipFlavor;
+        CFRelease(hOldFlavor);
+        *phStrOwnershipFlavor = NULL;
+    }
+
     /*
      * Clear the pasteboard and take ownership over it.
@@ -322,9 +374,14 @@
                                               hFlavor, hData, kPasteboardFlavorNoFlags);
                 if (orc == 0)
+                {
+                    *phStrOwnershipFlavor = (void *)hFlavor;
                     Log(("takePasteboardOwnership: idOwnership=%RX64 flavor=%s value=%s\n",
                          idOwnership, pszOwnershipFlavor, pszOwnershipValue));
+                }
                 else
+                {
                     Log(("takePasteboardOwnership: PasteboardPutItemFlavor -> %d (%#x)!\n", orc, orc));
-                CFRelease(hFlavor);
+                    CFRelease(hFlavor);
+                }
             }
             else
@@ -414,10 +471,10 @@
                         rc = VERR_GENERAL_FAILURE;
                     }
-                    else
-                    {
-                        Log(("writeToPasteboard: CFDataCreate/UTF16 failed!\n"));
-                        rc = VERR_NO_MEMORY;
-                    }
                     CFRelease(hData);
+                }
+                else
+                {
+                    Log(("writeToPasteboard: CFDataCreate/UTF16 failed!\n"));
+                    rc = VERR_NO_MEMORY;
                 }
             }
Index: /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h	(revision 83631)
+++ /trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.h	(revision 83632)
@@ -27,8 +27,9 @@
 void destroyPasteboard(PasteboardRef *pPasteboardRef);
 
-int queryNewPasteboardFormats(PasteboardRef pPasteboard, uint32_t *pfFormats, bool *pfChanged);
+int queryNewPasteboardFormats(PasteboardRef hPasteboard, uint64_t idOwnership, void *hStrOwnershipFlavor,
+                              uint32_t *pfFormats, bool *pfChanged);
 int readFromPasteboard(PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual);
-int takePasteboardOwnership(PasteboardRef pPasteboard, uint64_t idOwnership,
-                            const char *pszOwnershipFlavor, const char *pszOwnershipValue);
+int takePasteboardOwnership(PasteboardRef pPasteboard, uint64_t idOwnership, const char *pszOwnershipFlavor,
+                            const char *pszOwnershipValue, void **phStrOwnershipFlavor);
 int writeToPasteboard(PasteboardRef hPasteboard, uint64_t idOwnership, void const *pv, uint32_t cb, uint32_t fFormat);
 
