Bug 1261299 - Add method nsCopySupport::ClearSelectionTransferable() to clear the nsClipboard::sSelectionTransferable when you have no content selection. r=mstange
authorJimmy Wang <jimmyw22@gmail.com>
Wed, 08 Jun 2016 14:11:39 -0400
changeset 351154 6888ab7ba2f3467c3f89941034d5d0b5538cdf84
parent 351153 fb83488b8880a9d8a4c97089fbf5f3c5a3b0301c
child 351155 02eede58003bb7854c238a940597cc8cf024e0d1
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1261299
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1261299 - Add method nsCopySupport::ClearSelectionTransferable() to clear the nsClipboard::sSelectionTransferable when you have no content selection. r=mstange 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;
 
 };