Bug 1689992: part 1) When copying an image, add the image data before other data to the transferable and macOS's pasteboard. r=masayuki

On macOS, the Pages app depends on the order of the pasteboard
flavors, although it shouldn't, according to Apple's Programming Guide
<https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/PasteboardGuide106/Articles/pbConcepts.html#//apple_ref/doc/uid/TP40008101-SW1>.

I don't know how to write an automated test for this. Exporting the
flavors to the clipboard can be triggered by a Mochitest, but it doesn't
allow reading from macOS's native pasteboard.

Checking the "paste" event doesn't cover this scenario either and the
order of its flavors is not affected by this change. So that's not
usable as an indirect test.

Writing a unit test for `nsCopySupport::ImageCopy` is also insufficient,
because the produced transferable still has to be propagated to the
pasteboard, which could alter the order.

In theory, one would have to run a mochitest which exports to the
clipboard and then run a separate executable which checks the
pasteboard's content. However, it seems Gecko's test-harness doesn't
provide this and extending it seems infeasible.

Differential Revision: https://phabricator.services.mozilla.com/D104704
This commit is contained in:
Mirko Brodesser 2021-02-19 09:04:35 +00:00
Родитель 373e080995
Коммит de0f7846d5
2 изменённых файлов: 26 добавлений и 0 удалений

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

@ -8,6 +8,7 @@
#include "nsIClipboard.h"
#include "nsString.h"
#include "mozilla/Maybe.h"
#include "mozilla/StaticPtr.h"
#import <Cocoa/Cocoa.h>
@ -47,6 +48,9 @@ class nsClipboard : public nsIClipboard {
private:
virtual ~nsClipboard();
static mozilla::Maybe<uint32_t> FindIndexOfImageFlavor(const nsTArray<nsCString>& aMIMETypes);
int32_t mCachedClipboard;
int32_t mChangeCount; // Set to the native change count after any modification of the clipboard.

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

@ -3,6 +3,8 @@
* 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/. */
#include <algorithm>
#include "mozilla/Logging.h"
#include "mozilla/Unused.h"
@ -433,6 +435,18 @@ nsClipboard::SupportsFindClipboard(bool* _retval) {
return NS_OK;
}
// static
mozilla::Maybe<uint32_t> nsClipboard::FindIndexOfImageFlavor(
const nsTArray<nsCString>& aMIMETypes) {
for (uint32_t i = 0; i < aMIMETypes.Length(); ++i) {
if (nsClipboard::IsImageType(aMIMETypes[i])) {
return mozilla::Some(i);
}
}
return mozilla::Nothing();
}
// This function converts anything that other applications might understand into the system format
// and puts it into a dictionary which it returns.
// static
@ -451,6 +465,14 @@ NSDictionary* nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTran
return nil;
}
const mozilla::Maybe<uint32_t> imageFlavorIndex = nsClipboard::FindIndexOfImageFlavor(flavors);
if (imageFlavorIndex) {
// When right-clicking and "Copy Image" is clicked on macOS, some apps expect the
// first flavor to be the image flavor. See bug 1689992. For other apps, the
// order shouldn't matter.
std::swap(*flavors.begin(), flavors[*imageFlavorIndex]);
}
for (uint32_t i = 0; i < flavors.Length(); i++) {
nsCString& flavorStr = flavors[i];