Bug 1810850 - Part 1: Track clipboard change count in clipboard cache; r=cmartin,mstange

We also need to update clipboard cache after setting native clipboard,
in order to obtain the correct clipboard change count.

Differential Revision: https://phabricator.services.mozilla.com/D178777
This commit is contained in:
Edgar Chen 2023-06-26 10:03:22 +00:00
Родитель ea012bcbbf
Коммит 94708c1baf
6 изменённых файлов: 55 добавлений и 7 удалений

Просмотреть файл

@ -32,6 +32,7 @@ class nsClipboard : public nsBaseClipboard {
// in the parent process. This is needed for the services menu which
// requires synchronous access to the current selection.
static mozilla::StaticRefPtr<nsITransferable> sSelectionCache;
static int32_t sSelectionCacheChangeCount;
// Helper methods, used also by nsDragService
static NSDictionary* PasteboardDictFromTransferable(nsITransferable* aTransferable);
@ -47,6 +48,9 @@ class nsClipboard : public nsBaseClipboard {
int32_t aWhichClipboard) override;
NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
int32_t aWhichClipboard) override;
mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) override;
void ClearSelectionCache();
void SetSelectionCache(nsITransferable* aTransferable);

Просмотреть файл

@ -29,6 +29,7 @@ using mozilla::gfx::DataSourceSurface;
using mozilla::gfx::SourceSurface;
mozilla::StaticRefPtr<nsITransferable> nsClipboard::sSelectionCache;
int32_t nsClipboard::sSelectionCacheChangeCount = 0;
nsClipboard::nsClipboard()
: nsBaseClipboard(mozilla::dom::ClipboardCapabilities(false /* supportsSelectionClipboard */,
@ -75,10 +76,11 @@ static NSPasteboard* GetPasteboard(int32_t aWhichClipboard) {
} // namespace
void nsClipboard::SetSelectionCache(nsITransferable* aTransferable) {
sSelectionCacheChangeCount++;
sSelectionCache = aTransferable;
}
void nsClipboard::ClearSelectionCache() { sSelectionCache = nullptr; }
void nsClipboard::ClearSelectionCache() { SetSelectionCache(nullptr); }
NS_IMETHODIMP
nsClipboard::SetNativeClipboardData(nsITransferable* aTransferable, nsIClipboardOwner* aOwner,
@ -774,3 +776,23 @@ nsClipboard::EmptyClipboard(int32_t aWhichClipboard) {
NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
}
mozilla::Result<int32_t, nsresult> nsClipboard::GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) {
NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
MOZ_DIAGNOSTIC_ASSERT(nsIClipboard::IsClipboardTypeSupported(aWhichClipboard));
if (kSelectionCache == aWhichClipboard) {
return sSelectionCacheChangeCount;
}
NSPasteboard* cocoaPasteboard = GetPasteboard(aWhichClipboard);
if (!cocoaPasteboard) {
return mozilla::Err(NS_ERROR_FAILURE);
}
return [cocoaPasteboard changeCount];
NS_OBJC_END_TRY_BLOCK_RETURN(mozilla::Err(NS_ERROR_FAILURE));
}

Просмотреть файл

@ -158,9 +158,11 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable* aTransferable,
int32_t aWhichClipboard) {
NS_ASSERTION(aTransferable, "clipboard given a null transferable");
CLIPBOARD_LOG("%s", __FUNCTION__);
CLIPBOARD_LOG("%s: clipboard=%d", __FUNCTION__, aWhichClipboard);
if (!nsIClipboard::IsClipboardTypeSupported(aWhichClipboard)) {
CLIPBOARD_LOG("%s: clipboard %d is not supported.", __FUNCTION__,
aWhichClipboard);
return NS_ERROR_FAILURE;
}
@ -178,8 +180,6 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable* aTransferable,
}
mEmptyingForSetData = false;
clipboardCache->Update(aTransferable, anOwner);
nsresult rv = NS_ERROR_FAILURE;
if (aTransferable) {
mIgnoreEmptyNotification = true;
@ -189,9 +189,18 @@ NS_IMETHODIMP nsBaseClipboard::SetData(nsITransferable* aTransferable,
}
if (NS_FAILED(rv)) {
CLIPBOARD_LOG("%s: setting native clipboard data failed.", __FUNCTION__);
return rv;
}
return rv;
auto result = GetNativeClipboardSequenceNumber(aWhichClipboard);
if (result.isErr()) {
CLIPBOARD_LOG("%s: getting native clipboard change count failed.",
__FUNCTION__);
return result.unwrapErr();
}
clipboardCache->Update(aTransferable, anOwner, result.unwrap());
return NS_OK;
}
/**
@ -298,4 +307,5 @@ void nsBaseClipboard::ClipboardCache::Clear() {
mClipboardOwner = nullptr;
}
mTransferable = nullptr;
mSequenceNumber = -1;
}

Просмотреть файл

@ -8,7 +8,7 @@
#include "mozilla/dom/PContent.h"
#include "mozilla/Logging.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Result.h"
#include "nsIClipboard.h"
#include "nsITransferable.h"
#include "nsCOMPtr.h"
@ -124,6 +124,8 @@ class nsBaseClipboard : public ClipboardSetDataHelper {
// Implement the native clipboard behavior.
NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
int32_t aWhichClipboard) = 0;
virtual mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) = 0;
class ClipboardCache final {
public:
@ -138,11 +140,12 @@ class nsBaseClipboard : public ClipboardSetDataHelper {
*/
void Clear();
void Update(nsITransferable* aTransferable,
nsIClipboardOwner* aClipboardOwner) {
nsIClipboardOwner* aClipboardOwner, int32_t aSequenceNumber) {
// Clear first to notify the old clipboard owner.
Clear();
mTransferable = aTransferable;
mClipboardOwner = aClipboardOwner;
mSequenceNumber = aSequenceNumber;
}
nsITransferable* GetTransferable() const { return mTransferable; }
nsIClipboardOwner* GetClipboardOwner() const { return mClipboardOwner; }
@ -150,6 +153,7 @@ class nsBaseClipboard : public ClipboardSetDataHelper {
private:
nsCOMPtr<nsITransferable> mTransferable;
nsCOMPtr<nsIClipboardOwner> mClipboardOwner;
int32_t mSequenceNumber = -1;
};
mozilla::UniquePtr<ClipboardCache> mCaches[nsIClipboard::kClipboardTypeCount];

Просмотреть файл

@ -1356,6 +1356,12 @@ nsClipboard::EmptyClipboard(int32_t aWhichClipboard) {
return nsBaseClipboard::EmptyClipboard(aWhichClipboard);
}
Result<int32_t, nsresult> nsClipboard::GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) {
MOZ_DIAGNOSTIC_ASSERT(kGlobalClipboard == aWhichClipboard);
return (int32_t)::GetClipboardSequenceNumber();
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(
const nsTArray<nsCString>& aFlavorList, int32_t aWhichClipboard,

Просмотреть файл

@ -82,6 +82,8 @@ class nsClipboard : public nsBaseClipboard, public nsIObserver {
int32_t aWhichClipboard) override;
NS_IMETHOD GetNativeClipboardData(nsITransferable* aTransferable,
int32_t aWhichClipboard) override;
mozilla::Result<int32_t, nsresult> GetNativeClipboardSequenceNumber(
int32_t aWhichClipboard) override;
static bool IsInternetShortcut(const nsAString& inFileName);
static bool FindURLFromLocalFile(IDataObject* inDataObject, UINT inIndex,