xcb: Correctly report whether QInternalMimeData::retrieveData_sys() fails
QMimeData::retrieveData() checks whether the returned QVariant value is valid, i.e. the variant contains some data. If the variant contains an empty QByteArray, it will be considered valid. So retrieveData_sys() should return QVariant() in case data with the specified mime type cannot be retrieved. Fixes: QTBUG-125531 Pick-to: 6.5 6.2 5.15 Change-Id: I0a668ca7ad5b2c5430335e8554cc597747287173 Reviewed-by: Liang Qi <liang.qi@qt.io> (cherry picked from commit 59b7e143a98c1a91587f8cc87e92c0bc0650f55d) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
2267382273
commit
7f219f23b4
@ -61,7 +61,7 @@ protected:
|
|||||||
// get the list of targets from the current clipboard owner - we do this
|
// get the list of targets from the current clipboard owner - we do this
|
||||||
// once so that multiple calls to this function don't require multiple
|
// once so that multiple calls to this function don't require multiple
|
||||||
// server round trips...
|
// server round trips...
|
||||||
that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::AtomTARGETS));
|
that->format_atoms = m_clipboard->getDataInFormat(modeAtom, m_clipboard->atom(QXcbAtom::AtomTARGETS)).value_or(QByteArray());
|
||||||
|
|
||||||
if (format_atoms.size() > 0) {
|
if (format_atoms.size() > 0) {
|
||||||
const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data();
|
const xcb_atom_t *targets = (const xcb_atom_t *) format_atoms.data();
|
||||||
@ -91,7 +91,7 @@ protected:
|
|||||||
{
|
{
|
||||||
auto requestedType = type;
|
auto requestedType = type;
|
||||||
if (fmt.isEmpty() || isEmpty())
|
if (fmt.isEmpty() || isEmpty())
|
||||||
return QByteArray();
|
return QVariant();
|
||||||
|
|
||||||
(void)formats(); // trigger update of format list
|
(void)formats(); // trigger update of format list
|
||||||
|
|
||||||
@ -108,7 +108,11 @@ protected:
|
|||||||
if (fmtatom == 0)
|
if (fmtatom == 0)
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
return mimeConvertToFormat(m_clipboard->connection(), fmtatom, m_clipboard->getDataInFormat(modeAtom, fmtatom), fmt, requestedType, hasUtf8);
|
const std::optional<QByteArray> result = m_clipboard->getDataInFormat(modeAtom, fmtatom);
|
||||||
|
if (!result.has_value())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
return mimeConvertToFormat(m_clipboard->connection(), fmtatom, result.value(), fmt, requestedType, hasUtf8);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -776,7 +780,7 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, i
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
|
std::optional<QByteArray> QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm)
|
||||||
{
|
{
|
||||||
QByteArray buf;
|
QByteArray buf;
|
||||||
QByteArray tmp_buf;
|
QByteArray tmp_buf;
|
||||||
@ -841,17 +845,16 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
|
|||||||
// could consider next request to be still part of this timed out request
|
// could consider next request to be still part of this timed out request
|
||||||
setRequestor(0);
|
setRequestor(0);
|
||||||
|
|
||||||
return QByteArray();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)
|
std::optional<QByteArray> QXcbClipboard::getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtAtom)
|
||||||
{
|
{
|
||||||
return getSelection(modeAtom, fmtAtom, atom(QXcbAtom::Atom_QT_SELECTION));
|
return getSelection(modeAtom, fmtAtom, atom(QXcbAtom::Atom_QT_SELECTION));
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t time)
|
std::optional<QByteArray> QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t time)
|
||||||
{
|
{
|
||||||
QByteArray buf;
|
|
||||||
xcb_window_t win = requestor();
|
xcb_window_t win = requestor();
|
||||||
|
|
||||||
if (time == 0) time = connection()->time();
|
if (time == 0) time = connection()->time();
|
||||||
@ -866,17 +869,19 @@ QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target,
|
|||||||
free(ge);
|
free(ge);
|
||||||
|
|
||||||
if (no_selection)
|
if (no_selection)
|
||||||
return buf;
|
return std::nullopt;
|
||||||
|
|
||||||
xcb_atom_t type;
|
xcb_atom_t type;
|
||||||
|
QByteArray buf;
|
||||||
if (clipboardReadProperty(win, property, true, &buf, nullptr, &type, nullptr)) {
|
if (clipboardReadProperty(win, property, true, &buf, nullptr, &type, nullptr)) {
|
||||||
if (type == atom(QXcbAtom::AtomINCR)) {
|
if (type == atom(QXcbAtom::AtomINCR)) {
|
||||||
int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
|
int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
|
||||||
buf = clipboardReadIncrementalProperty(win, property, nbytes, false);
|
return clipboardReadIncrementalProperty(win, property, nbytes, false);
|
||||||
}
|
}
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // QT_NO_CLIPBOARD
|
#endif // QT_NO_CLIPBOARD
|
||||||
|
@ -67,13 +67,13 @@ public:
|
|||||||
void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event);
|
void handleXFixesSelectionRequest(xcb_xfixes_selection_notify_event_t *event);
|
||||||
|
|
||||||
bool clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format);
|
bool clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format);
|
||||||
QByteArray clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm);
|
std::optional<QByteArray> clipboardReadIncrementalProperty(xcb_window_t win, xcb_atom_t property, int nbytes, bool nullterm);
|
||||||
|
|
||||||
QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
|
std::optional<QByteArray> getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom);
|
||||||
|
|
||||||
bool handlePropertyNotify(const xcb_generic_event_t *event);
|
bool handlePropertyNotify(const xcb_generic_event_t *event);
|
||||||
|
|
||||||
QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
|
std::optional<QByteArray> getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0);
|
||||||
|
|
||||||
int increment() const { return m_maxPropertyRequestDataBytes; }
|
int increment() const { return m_maxPropertyRequestDataBytes; }
|
||||||
int clipboardTimeout() const { return clipboard_timeout; }
|
int clipboardTimeout() const { return clipboard_timeout; }
|
||||||
|
@ -1306,32 +1306,33 @@ QVariant QXcbDropData::retrieveData_sys(const QString &mimetype, QMetaType reque
|
|||||||
|
|
||||||
QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QMetaType requestedType) const
|
QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QMetaType requestedType) const
|
||||||
{
|
{
|
||||||
QByteArray result;
|
|
||||||
|
|
||||||
QXcbConnection *c = drag->connection();
|
QXcbConnection *c = drag->connection();
|
||||||
QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
|
QXcbWindow *xcb_window = c->platformWindowFromId(drag->xdnd_dragsource);
|
||||||
if (xcb_window && drag->currentDrag() && xcb_window->window()->type() != Qt::Desktop) {
|
if (xcb_window && drag->currentDrag() && xcb_window->window()->type() != Qt::Desktop) {
|
||||||
QMimeData *data = drag->currentDrag()->mimeData();
|
QMimeData *data = drag->currentDrag()->mimeData();
|
||||||
if (data->hasFormat(QLatin1StringView(format)))
|
if (data->hasFormat(QLatin1StringView(format)))
|
||||||
result = data->data(QLatin1StringView(format));
|
return data->data(QLatin1StringView(format));
|
||||||
return result;
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<xcb_atom_t> atoms = drag->xdnd_types;
|
QList<xcb_atom_t> atoms = drag->xdnd_types;
|
||||||
bool hasUtf8 = false;
|
bool hasUtf8 = false;
|
||||||
xcb_atom_t a = mimeAtomForFormat(c, QLatin1StringView(format), requestedType, atoms, &hasUtf8);
|
xcb_atom_t a = mimeAtomForFormat(c, QLatin1StringView(format), requestedType, atoms, &hasUtf8);
|
||||||
if (a == XCB_NONE)
|
if (a == XCB_NONE)
|
||||||
return result;
|
return QVariant();
|
||||||
|
|
||||||
#ifndef QT_NO_CLIPBOARD
|
#ifndef QT_NO_CLIPBOARD
|
||||||
if (c->selectionOwner(c->atom(QXcbAtom::AtomXdndSelection)) == XCB_NONE)
|
if (c->selectionOwner(c->atom(QXcbAtom::AtomXdndSelection)) == XCB_NONE)
|
||||||
return result; // should never happen?
|
return QVariant(); // should never happen?
|
||||||
|
|
||||||
xcb_atom_t xdnd_selection = c->atom(QXcbAtom::AtomXdndSelection);
|
xcb_atom_t xdnd_selection = c->atom(QXcbAtom::AtomXdndSelection);
|
||||||
result = c->clipboard()->getSelection(xdnd_selection, a, xdnd_selection, drag->targetTime());
|
const std::optional<QByteArray> result = c->clipboard()->getSelection(xdnd_selection, a, xdnd_selection, drag->targetTime());
|
||||||
|
if (!result.has_value())
|
||||||
|
return QVariant();
|
||||||
|
return mimeConvertToFormat(c, a, result.value(), QLatin1StringView(format), requestedType, hasUtf8);
|
||||||
|
#else
|
||||||
|
return QVariant();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return mimeConvertToFormat(c, a, result, QLatin1StringView(format), requestedType, hasUtf8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QXcbDropData::hasFormat_sys(const QString &format) const
|
bool QXcbDropData::hasFormat_sys(const QString &format) const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user