macOS: support copying lazily provided data to the clipboard

Using always EagerRequest type forces the application to provide the
data at copy or drag-begin time, even though the data might never be
requested (pasted or dropped into another application). For data that
is expensive to generate, this is wasteful, and on other platforms Qt
uses the functionality provided by the native clipboard to allow for
on-demand retrieval of data.

Changing the request type to LazyRequest for the cocoa clipboard works,
but then we need to make sure that we resolve all promises at shutdown
time so that the data is available (which is what the end user expects).
Commit ad0d2f463a disabled this for
lazy requests to prevent crashes when using drag'n'drop, where the
QMacPasteboard object is short-lived and stack allocated. We definitely
don't need to worry about lazy data that is not yet retrieved at the
end of a drag'n'drop operation, so limit the fix from the previous
commit to the drag'n'drop scenario.

[ChangeLog][QtGui][QClipboard] Support lazily provided copying of data
to the clipboard on macOS

Change-Id: Id2203999024a0d9d854d6933d39077cc4af925d0
Fixes: QTBUG-76263
Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Volker Hilsheimer 2019-12-04 15:06:36 +01:00
parent c978de990b
commit c69a2448ab
2 changed files with 7 additions and 3 deletions

View File

@ -67,7 +67,7 @@ void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
}
pasteBoard->sync();
pasteBoard->setMimeData(data);
pasteBoard->setMimeData(data, QMacPasteboard::LazyRequest);
emitChanged(mode);
}
}

View File

@ -138,8 +138,12 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt)
QMacPasteboard::~QMacPasteboard()
{
// commit all promises for paste after exit close
resolvingBeforeDestruction = true;
/*
Commit all promises for paste when shutting down,
unless we are the stack-allocated clipboard used by QCocoaDrag.
*/
if (mime_type == QMacInternalPasteboardMime::MIME_DND)
resolvingBeforeDestruction = true;
PasteboardResolvePromises(paste);
if (paste)
CFRelease(paste);