Bug 1355147 - Use headless clipboard on macOS. r?jrmuizel draft
authorBrendan Dahl <brendan.dahl@gmail.com>
Wed, 12 Jul 2017 11:52:30 -0700
changeset 616077 0a8dcfbed1a6c5e7f5c9f3b7f66a286d1aa32440
parent 616076 0f41da680db7e2bf264caf5ebcaa8e989cae7c28
child 639356 3c4ba99e91ea63a8b3da17cb35cb602cee0a8ed9
push id70562
push userbmo:bdahl@mozilla.com
push dateWed, 26 Jul 2017 17:30:17 +0000
reviewersjrmuizel
bugs1355147
milestone56.0a1
Bug 1355147 - Use headless clipboard on macOS. r?jrmuizel MozReview-Commit-ID: Fh0GHE34joE
widget/cocoa/nsClipboard.h
widget/cocoa/nsClipboard.mm
widget/cocoa/nsWidgetFactory.mm
--- a/widget/cocoa/nsClipboard.h
+++ b/widget/cocoa/nsClipboard.h
@@ -22,16 +22,18 @@ class nsClipboard : public nsIClipboard
 {
 
 public:
   nsClipboard();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSICLIPBOARD
 
+  static already_AddRefed<nsIClipboard> GetInstance();
+
   // On macOS, cache the transferable of the current selection (chrome/content)
   // in the parent process. This is needed for the services menu which
   // requires synchronous access to the current selection.
   static mozilla::StaticRefPtr<nsITransferable> sSelectionCache;
 
   // Helper methods, used also by nsDragService
   static NSDictionary* PasteboardDictFromTransferable(nsITransferable *aTransferable);
   // aPasteboardType is being retained and needs to be released by the caller.
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -6,16 +6,18 @@
 #include "mozilla/Logging.h"
 
 #include "mozilla/Unused.h"
 
 #include "gfxPlatform.h"
 #include "nsArrayUtils.h"
 #include "nsCOMPtr.h"
 #include "nsClipboard.h"
+#include "HeadlessClipboard.h"
+#include "mozilla/ClearOnShutdown.h"
 #include "nsString.h"
 #include "nsISupportsPrimitives.h"
 #include "nsXPIDLString.h"
 #include "nsPrimitiveHelpers.h"
 #include "nsMemory.h"
 #include "nsIFile.h"
 #include "nsStringStream.h"
 #include "nsDragService.h"
@@ -61,16 +63,39 @@ mozilla::StaticRefPtr<nsITransferable> n
                                                      kUTTypeData);
   NSString* result = [NSString stringWithString:dynamicType];
   [dynamicType release];
   return result;
 }
 
 @end // UTIHelper
 
+namespace mozilla {
+namespace clipboard {
+StaticRefPtr<nsIClipboard> sInstance;
+}
+}
+/* static */ already_AddRefed<nsIClipboard>
+nsClipboard::GetInstance()
+{
+  using namespace mozilla::clipboard;
+
+  if (!sInstance) {
+    if (gfxPlatform::IsHeadless()) {
+      sInstance = new mozilla::widget::HeadlessClipboard();
+    } else {
+      sInstance = new nsClipboard();
+    }
+    ClearOnShutdown(&sInstance);
+  }
+
+  RefPtr<nsIClipboard> service = sInstance.get();
+  return service.forget();
+}
+
 nsClipboard::nsClipboard()
   : mCachedClipboard(-1)
   , mChangeCount(0)
   , mIgnoreEmptyNotification(false)
 {
   EnsureLogInitialized();
 }
 
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -45,17 +45,17 @@ using namespace mozilla::widget;
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsCocoaWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildView)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFilePicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsColorPicker)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSound)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIClipboard, nsClipboard::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDragService)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceContextSpecX)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintOptionsX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintDialogServiceX, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintSession, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceX, nsIdleServiceX::GetInstance)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton)
@@ -126,17 +126,17 @@ static const mozilla::Module::CIDEntry k
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_COLORPICKER_CID, false, NULL, nsColorPickerConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_APPSHELL_CID, false, NULL, nsAppShellConstructor, mozilla::Module::ALLOW_IN_GPU_PROCESS },
   { &kNS_SOUND_CID, false, NULL, nsSoundConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_TRANSFERABLE_CID, false, NULL, nsTransferableConstructor },
   { &kNS_HTMLFORMATCONVERTER_CID, false, NULL, nsHTMLFormatConverterConstructor },
-  { &kNS_CLIPBOARD_CID, false, NULL, nsClipboardConstructor,
+  { &kNS_CLIPBOARD_CID, false, NULL, nsIClipboardConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_CLIPBOARDHELPER_CID, false, NULL, nsClipboardHelperConstructor },
   { &kNS_DRAGSERVICE_CID, false, NULL, nsDragServiceConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_BIDIKEYBOARD_CID, false, NULL, nsBidiKeyboardConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_THEMERENDERER_CID, false, NULL, nsNativeThemeCocoaConstructor },
   { &kNS_SCREENMANAGER_CID, false, NULL, ScreenManagerConstructor,