Bug 1261299 - Add method nsCopySupport::ClearSelectionTransferable() to clear the nsClipboard::sSelectionTransferable when you have no content selection. draft
authorJimmy Wang <jimmyw22@gmail.com>
Wed, 08 Jun 2016 14:11:39 -0400
changeset 401292 d8665bd32fba1af940db4cd8f8b7c2c8b85e8df6
parent 401291 aeb0e9d2dc47fb4ac428d7d68151607ecd7bdbbc
child 401293 000d45638cf2da6e40ecad4e097eeeed3cfaa8d8
push id26424
push userjimmyw22@gmail.com
push dateTue, 16 Aug 2016 21:05:59 +0000
bugs1261299
milestone51.0a1
Bug 1261299 - Add method nsCopySupport::ClearSelectionTransferable() to clear the nsClipboard::sSelectionTransferable when you have no content selection. MozReview-Commit-ID: AjUe94N0Iiw
dom/base/nsCopySupport.cpp
dom/base/nsCopySupport.h
layout/generic/nsSelection.cpp
widget/cocoa/nsClipboard.h
widget/cocoa/nsClipboard.mm
widget/nsBaseClipboard.cpp
widget/nsBaseClipboard.h
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -303,16 +303,25 @@ nsCopySupport::HTMLCopy(nsISelection* aS
   uint32_t flags = nsIDocumentEncoder::SkipInvisibleContent;
   if (aWithRubyAnnotation) {
     flags |= nsIDocumentEncoder::OutputRubyAnnotation;
   }
   return SelectionCopyHelper(aSel, aDoc, true, aClipboardID, flags, nullptr);
 }
 
 nsresult
+nsCopySupport::ClearSelectionCache()
+{
+  nsresult rv;
+  nsCOMPtr<nsIClipboard> clipboard = do_GetService(kCClipboardCID, &rv);
+  clipboard->EmptyClipboard(nsIClipboard::kSelectionCache);
+  return rv;
+}
+
+nsresult
 nsCopySupport::GetTransferableForSelection(nsISelection* aSel,
                                            nsIDocument* aDoc,
                                            nsITransferable** aTransferable)
 {
   return SelectionCopyHelper(aSel, aDoc, false, 0,
                              nsIDocumentEncoder::SkipInvisibleContent,
                              aTransferable);
 }
--- a/dom/base/nsCopySupport.h
+++ b/dom/base/nsCopySupport.h
@@ -20,16 +20,17 @@ class nsACString;
 class nsAString;
 class nsIPresShell;
 class nsILoadContext;
 
 class nsCopySupport
 {
   // class of static helper functions for copy support
   public:
+    static nsresult ClearSelectionCache();
     static nsresult HTMLCopy(nsISelection *aSel, nsIDocument *aDoc,
                              int16_t aClipboardID, bool aWithRubyAnnotation);
     static nsresult DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
                             bool *aDoPutOnClipboard);
 
     // Get the selection, or entire document, in the format specified by the mime type
     // (text/html or text/plain). If aSel is non-null, use it, otherwise get the entire
     // doc.
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -6490,16 +6490,21 @@ nsAutoCopyListener::NotifySelectionChang
     return NS_OK; //dont care if we are still dragging
 
   bool collapsed;
   if (!aDoc || !aSel ||
       NS_FAILED(aSel->GetIsCollapsed(&collapsed)) || collapsed) {
 #ifdef DEBUG_CLIPBOARD
     fprintf(stderr, "CLIPBOARD: no selection/collapsed selection\n");
 #endif
+    // If on macOS, clear the current selection transferable cached
+    // on the parent process (nsClipboard) when the selection is empty.
+    if (mCachedClipboard == nsIClipboard::kSelectionCache) {
+      return nsCopySupport::ClearSelectionCache();
+    }
     /* clear X clipboard? */
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   // call the copy code
--- a/widget/cocoa/nsClipboard.h
+++ b/widget/cocoa/nsClipboard.h
@@ -37,16 +37,17 @@ public:
   static NSString* WrapHtmlForSystemPasteboard(NSString* aString);
   static nsresult TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteboard *pboard);
 
 protected:
 
   // impelement the native clipboard behavior
   NS_IMETHOD SetNativeClipboardData(int32_t aWhichClipboard);
   NS_IMETHOD GetNativeClipboardData(nsITransferable * aTransferable, int32_t aWhichClipboard);
+  void ClearSelectionCache();
   void SetSelectionCache(nsITransferable* aTransferable);
   
 private:
   int32_t mCachedClipboard;
   int32_t mChangeCount; // Set to the native change count after any modification of the clipboard.
 };
 
 #endif // nsClipboard_h_
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -68,16 +68,22 @@ GetDataFromPasteboard(NSPasteboard* aPas
 }
 
 void
 nsClipboard::SetSelectionCache(nsITransferable *aTransferable)
 {
   sSelectionCache = aTransferable;
 }
 
+void
+nsClipboard::ClearSelectionCache()
+{
+  sSelectionCache = nullptr;
+}
+
 NS_IMETHODIMP
 nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !mTransferable)
     return NS_ERROR_FAILURE;
 
--- a/widget/nsBaseClipboard.cpp
+++ b/widget/nsBaseClipboard.cpp
@@ -84,16 +84,21 @@ NS_IMETHODIMP nsBaseClipboard::GetData(n
   if ( aTransferable )
     return GetNativeClipboardData(aTransferable, aWhichClipboard);
 
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsBaseClipboard::EmptyClipboard(int32_t aWhichClipboard)
 {
+  if (aWhichClipboard == kSelectionCache) {
+    ClearSelectionCache();
+    return NS_OK;
+  }
+
   bool selectClipPresent;
   SupportsSelectionClipboard(&selectClipPresent);
   bool findClipPresent;
   SupportsFindClipboard(&findClipPresent);
   if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard)
     return NS_ERROR_FAILURE;
 
   if (mIgnoreEmptyNotification)
--- a/widget/nsBaseClipboard.h
+++ b/widget/nsBaseClipboard.h
@@ -29,16 +29,17 @@ public:
   // nsIClipboard  
   NS_DECL_NSICLIPBOARD
   
 protected:
   virtual ~nsBaseClipboard();
 
   NS_IMETHOD SetNativeClipboardData ( int32_t aWhichClipboard ) = 0;
   NS_IMETHOD GetNativeClipboardData ( nsITransferable * aTransferable, int32_t aWhichClipboard ) = 0;
+  virtual void ClearSelectionCache () = 0;
   virtual void SetSelectionCache (nsITransferable* aTransferable) = 0;
 
   bool                mEmptyingForSetData;
   bool                mIgnoreEmptyNotification;
   nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
   nsCOMPtr<nsITransferable>   mTransferable;
 
 };