Bug 1261299 - Implement nsIClipboard methods in nsClipboard.mm with methods specific for osx. (EmptyClipboard, SetData) methods modified from nsBaseClipboard to also set the current selection cache.
MozReview-Commit-ID: D8aRmK6FAai
--- a/widget/cocoa/nsClipboard.h
+++ b/widget/cocoa/nsClipboard.h
@@ -1,35 +1,32 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsClipboard_h_
#define nsClipboard_h_
-#include "nsBaseClipboard.h"
+#include "nsIClipboard.h"
#include "nsXPIDLString.h"
#include "mozilla/StaticPtr.h"
#import <Cocoa/Cocoa.h>
class nsITransferable;
-class nsClipboard : public nsBaseClipboard
+class nsClipboard : public nsIClipboard
{
public:
nsClipboard();
- virtual ~nsClipboard();
- // nsIClipboard
- NS_IMETHOD HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength,
- int32_t aWhichClipboard, bool *_retval);
- NS_IMETHOD SupportsFindClipboard(bool *_retval);
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICLIPBOARD
// 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);
@@ -41,13 +38,18 @@ 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:
+ virtual ~nsClipboard();
int32_t mCachedClipboard;
int32_t mChangeCount; // Set to the native change count after any modification of the clipboard.
+
+ bool mIgnoreEmptyNotification;
+ nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
+ nsCOMPtr<nsITransferable> mTransferable;
};
#endif // nsClipboard_h_
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -32,29 +32,33 @@ using mozilla::LogLevel;
#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil
extern PRLogModuleInfo* sCocoaLog;
extern void EnsureLogInitialized();
mozilla::StaticRefPtr<nsITransferable> nsClipboard::sSelectionCache;
-nsClipboard::nsClipboard() : nsBaseClipboard()
+nsClipboard::nsClipboard()
+ : mCachedClipboard(-1)
+ , mChangeCount(0)
+ , mIgnoreEmptyNotification(false)
{
- mCachedClipboard = -1;
- mChangeCount = 0;
-
EnsureLogInitialized();
}
nsClipboard::~nsClipboard()
{
- sSelectionCache = nullptr;
+ EmptyClipboard(kGlobalClipboard);
+ EmptyClipboard(kFindClipboard);
+ ClearSelectionCache();
}
+NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard)
+
// We separate this into its own function because after an @try, all local
// variables within that function get marked as volatile, and our C++ type
// system doesn't like volatile things.
static NSData*
GetDataFromPasteboard(NSPasteboard* aPasteboard, NSString* aType)
{
NSData *data = nil;
@try {
@@ -341,17 +345,17 @@ nsClipboard::GetNativeClipboardData(nsIT
rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(dataSupports), &dataSize);
if (NS_SUCCEEDED(rv)) {
aTransferable->SetTransferData(flavorStr, dataSupports, dataSize);
return NS_OK; // maybe try to fill in more types? Is there a point?
}
}
}
} else {
- nsBaseClipboard::EmptyClipboard(aWhichClipboard);
+ EmptyClipboard(aWhichClipboard);
}
// at this point we can't satisfy the request from cache data so let's look
// for things other people put on the system clipboard
return nsClipboard::TransferableFromPasteboard(aTransferable, cocoaPasteboard);
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
@@ -669,8 +673,109 @@ NSString* nsClipboard::WrapHtmlForSystem
"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"
"</head>"
"<body>"
"%@"
"</body>"
"</html>", aString];
return wrapped;
}
+
+/**
+ * Sets the transferable object
+ *
+ */
+NS_IMETHODIMP
+nsClipboard::SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner,
+ int32_t aWhichClipboard)
+{
+ NS_ASSERTION (aTransferable, "clipboard given a null transferable");
+
+ if (aWhichClipboard == kSelectionCache) {
+ if (aTransferable) {
+ SetSelectionCache(aTransferable);
+ return NS_OK;
+ }
+ return NS_ERROR_FAILURE;
+ }
+
+ if (aTransferable == mTransferable && anOwner == mClipboardOwner) {
+ return NS_OK;
+ }
+ bool selectClipPresent;
+ SupportsSelectionClipboard(&selectClipPresent);
+ bool findClipPresent;
+ SupportsFindClipboard(&findClipPresent);
+ if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) {
+ return NS_ERROR_FAILURE;
+ }
+
+ EmptyClipboard(aWhichClipboard);
+
+ mClipboardOwner = anOwner;
+ mTransferable = aTransferable;
+
+ nsresult rv = NS_ERROR_FAILURE;
+ if (mTransferable) {
+ rv = SetNativeClipboardData(aWhichClipboard);
+ }
+
+ return rv;
+}
+
+/**
+ * Gets the transferable object
+ *
+ */
+NS_IMETHODIMP
+nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard)
+{
+ NS_ASSERTION (aTransferable, "clipboard given a null transferable");
+
+ bool selectClipPresent;
+ SupportsSelectionClipboard(&selectClipPresent);
+ bool findClipPresent;
+ SupportsFindClipboard(&findClipPresent);
+ if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard)
+ return NS_ERROR_FAILURE;
+
+ if (aTransferable) {
+ return GetNativeClipboardData(aTransferable, aWhichClipboard);
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsClipboard::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) {
+ return NS_OK;
+ }
+
+ if (mClipboardOwner) {
+ mClipboardOwner->LosingOwnership(mTransferable);
+ mClipboardOwner = nullptr;
+ }
+
+ mTransferable = nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClipboard::SupportsSelectionClipboard(bool* _retval)
+{
+ *_retval = false; // we don't support the selection clipboard by default.
+ return NS_OK;
+}
\ No newline at end of file
--- a/widget/nsBaseClipboard.cpp
+++ b/widget/nsBaseClipboard.cpp
@@ -29,24 +29,16 @@ NS_IMPL_ISUPPORTS(nsBaseClipboard, nsICl
* Sets the transferable object
*
*/
NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable * aTransferable, nsIClipboardOwner * anOwner,
int32_t aWhichClipboard)
{
NS_ASSERTION ( aTransferable, "clipboard given a null transferable" );
- if (aWhichClipboard == kSelectionCache) {
- if (aTransferable) {
- SetSelectionCache(aTransferable);
- return NS_OK;
- }
- return NS_ERROR_FAILURE;
- }
-
if (aTransferable == mTransferable && anOwner == mClipboardOwner)
return NS_OK;
bool selectClipPresent;
SupportsSelectionClipboard(&selectClipPresent);
bool findClipPresent;
SupportsFindClipboard(&findClipPresent);
if ( !selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard )
return NS_ERROR_FAILURE;
@@ -84,21 +76,16 @@ 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,18 +29,16 @@ 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;
};