Bug 1261299 - Add new clipboard kSelectionCache to cache the current selection for OSX service menu. Add a constructor to nsAutoCopyListener which sets the clipboard to copy to. Pass in kSelectionCache for OSX or kSelectionClipboard for linux. draft
authorJimmy Wang <jimmyw22@gmail.com>
Fri, 03 Jun 2016 12:04:22 -0400
changeset 401290 0697674f9419cd1147f84b94844ac3c54044905f
parent 400825 054d4856cea6150a6638e5daf7913713281af97d
child 401291 aeb0e9d2dc47fb4ac428d7d68151607ecd7bdbbc
push id26424
push userjimmyw22@gmail.com
push dateTue, 16 Aug 2016 21:05:59 +0000
bugs1261299
milestone51.0a1
Bug 1261299 - Add new clipboard kSelectionCache to cache the current selection for OSX service menu. Add a constructor to nsAutoCopyListener which sets the clipboard to copy to. Pass in kSelectionCache for OSX or kSelectionClipboard for linux. MozReview-Commit-ID: B9mzVnJxUjl
layout/generic/nsAutoCopyListener.h
layout/generic/nsSelection.cpp
widget/nsIClipboard.idl
--- a/layout/generic/nsAutoCopyListener.h
+++ b/layout/generic/nsAutoCopyListener.h
@@ -11,37 +11,42 @@
 #include "mozilla/Attributes.h"
 
 class nsAutoCopyListener final : public nsISelectionListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISELECTIONLISTENER
 
+  explicit nsAutoCopyListener(int16_t aClipboardID)
+    : mCachedClipboard(aClipboardID)
+  {}
+
   void Listen(nsISelectionPrivate *aSelection)
   {
       NS_ASSERTION(aSelection, "Null selection passed to Listen()");
       aSelection->AddSelectionListener(this);
   }
 
-  static nsAutoCopyListener* GetInstance()
+  static nsAutoCopyListener* GetInstance(int16_t aClipboardID)
   {
     if (!sInstance) {
-      sInstance = new nsAutoCopyListener();
+      sInstance = new nsAutoCopyListener(aClipboardID);
 
       NS_ADDREF(sInstance);
     }
 
     return sInstance;
   }
 
   static void Shutdown()
   {
     NS_IF_RELEASE(sInstance);
   }
 
 private:
   ~nsAutoCopyListener() {}
 
   static nsAutoCopyListener* sInstance;
+  int16_t mCachedClipboard;
 };
 
 #endif
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -544,26 +544,32 @@ nsFrameSelection::nsFrameSelection()
   mHint = CARET_ASSOCIATE_BEFORE;
   mCaretBidiLevel = BIDI_LEVEL_UNDEFINED;
   mKbdBidiLevel = NSBIDI_LTR;
 
   mDragSelectingCells = false;
   mSelectingTableCellMode = 0;
   mSelectedCellIndex = 0;
 
+  nsAutoCopyListener *autoCopy = nullptr;
+  // On macOS, cache the current selection to send to osx service menu.
+#ifdef XP_MACOSX
+  autoCopy = nsAutoCopyListener::GetInstance(nsIClipboard::kSelectionCache);
+#endif
+
   // Check to see if the autocopy pref is enabled
   //   and add the autocopy listener if it is
   if (Preferences::GetBool("clipboard.autocopy")) {
-    nsAutoCopyListener *autoCopy = nsAutoCopyListener::GetInstance();
-
-    if (autoCopy) {
-      int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
-      if (mDomSelections[index]) {
-        autoCopy->Listen(mDomSelections[index]);
-      }
+    autoCopy = nsAutoCopyListener::GetInstance(nsIClipboard::kSelectionClipboard);
+  }
+
+  if (autoCopy) {
+    int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
+    if (mDomSelections[index]) {
+      autoCopy->Listen(mDomSelections[index]);
     }
   }
 
   mDisplaySelection = nsISelectionController::SELECTION_OFF;
   mSelectionChangeReason = nsISelectionListener::NO_REASON;
 
   mDelayedMouseEventValid = false;
   // These values are not used since they are only valid when
@@ -6462,16 +6468,21 @@ NS_IMPL_ISUPPORTS(nsAutoCopyListener, ns
  *   selections (or simple clicks, which currently cause a selection
  *   notification, regardless of if they're in the document which currently has
  *   selection!) don't lose the contents of the ``application''?  Or should we
  *   just put some intelligence in the ``is this a real selection?'' code to
  *   protect our selection against clicks in other documents that don't create
  *   selections?
  * - maybe we should just never clear the X clipboard?  That would make this 
  *   problem just go away, which is very tempting.
+ *
+ * On macOS,
+ * nsIClipboard::kSelectionCache is the flag for current selection cache.
+ * Set the current selection cache on the parent process in
+ * widget cocoa nsClipboard whenever selection changes.
  */
 
 NS_IMETHODIMP
 nsAutoCopyListener::NotifySelectionChanged(nsIDOMDocument *aDoc,
                                            nsISelection *aSel, int16_t aReason)
 {
   if (!(aReason & nsISelectionListener::MOUSEUP_REASON   || 
         aReason & nsISelectionListener::SELECTALL_REASON ||
@@ -6488,17 +6499,17 @@ nsAutoCopyListener::NotifySelectionChang
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   // call the copy code
   return nsCopySupport::HTMLCopy(aSel, doc,
-                                 nsIClipboard::kSelectionClipboard, false);
+                                 mCachedClipboard, false);
 }
 
 // SelectionChangeListener
 
 SelectionChangeListener::RawRangeData::RawRangeData(const nsRange* aRange)
 {
   mozilla::ErrorResult rv;
   mStartParent = aRange->GetStartContainer(rv);
--- a/widget/nsIClipboard.idl
+++ b/widget/nsIClipboard.idl
@@ -12,16 +12,18 @@
 interface nsIArray;
 
 [scriptable, uuid(ceaa0047-647f-4b8e-ad1c-aff9fa62aa51)]
 interface nsIClipboard : nsISupports
 {
     const long kSelectionClipboard = 0;
     const long kGlobalClipboard = 1;
     const long kFindClipboard = 2;
+    // Used to cache current selection on (nsClipboard) for macOS service menu.
+    const long kSelectionCache = 3;
     
    /**
     * Given a transferable, set the data on the native clipboard
     *
     * @param  aTransferable The transferable
     * @param  anOwner The owner of the transferable
     * @param  aWhichClipboard Specifies the clipboard to which this operation applies.
     * @result NS_Ok if no errors