Retrieve the actual data in the Wayland clipboard only when requested.

This commit is contained in:
Laszlo Agocs 2011-05-10 09:17:27 +02:00
parent 8fb5928469
commit 04549f2eed
2 changed files with 69 additions and 23 deletions

View File

@ -48,9 +48,48 @@
#include <QtCore/QStringList>
#include <QtCore/QFile>
#include <QtCore/QtDebug>
#include <QtGui/private/qdnd_p.h>
static QWaylandClipboard *clipboard;
class QWaylandMimeData : public QInternalMimeData
{
public:
void clearAll();
void setFormats(const QStringList &formatList);
bool hasFormat_sys(const QString &mimeType) const;
QStringList formats_sys() const;
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
private:
QStringList mFormatList;
};
void QWaylandMimeData::clearAll()
{
clear();
mFormatList.clear();
}
void QWaylandMimeData::setFormats(const QStringList &formatList)
{
mFormatList = formatList;
}
bool QWaylandMimeData::hasFormat_sys(const QString &mimeType) const
{
return formats().contains(mimeType);
}
QStringList QWaylandMimeData::formats_sys() const
{
return mFormatList;
}
QVariant QWaylandMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const
{
return clipboard->retrieveData(mimeType, type);
}
class QWaylandSelection
{
public:
@ -157,32 +196,35 @@ void QWaylandClipboard::forceRoundtrip(struct wl_display *display)
wl_display_iterate(display, WL_DISPLAY_READABLE);
}
QVariant QWaylandClipboard::retrieveData(const QString &mimeType, QVariant::Type type) const
{
Q_UNUSED(type);
int pipefd[2];
if (pipe(pipefd) == -1) {
qWarning("QWaylandClipboard: pipe() failed");
return QVariant();
}
QByteArray mimeTypeBa = mimeType.toLatin1();
wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]);
QByteArray content;
forceRoundtrip(mDisplay->wl_display());
char buf[256];
int n;
close(pipefd[1]);
while ((n = read(pipefd[0], &buf, sizeof buf)) > 0)
content.append(buf, n);
close(pipefd[0]);
return content;
}
const QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) const
{
Q_ASSERT(mode == QClipboard::Clipboard);
if (!mMimeDataIn)
mMimeDataIn = new QMimeData;
mMimeDataIn->clear();
if (!mOfferedMimeTypes.isEmpty() && mOffer) {
foreach (const QString &mimeType, mOfferedMimeTypes) {
int pipefd[2];
if (pipe(pipefd) == -1) {
qWarning("QWaylandClipboard::mimedata: pipe() failed");
break;
}
QByteArray mimeTypeBa = mimeType.toLatin1();
wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]);
QByteArray content;
forceRoundtrip(mDisplay->wl_display());
char buf[256];
int n;
close(pipefd[1]);
while ((n = read(pipefd[0], &buf, sizeof buf)) > 0)
content.append(buf, n);
close(pipefd[0]);
mMimeDataIn->setData(mimeType, content);
}
}
mMimeDataIn = new QWaylandMimeData;
mMimeDataIn->clearAll();
if (!mOfferedMimeTypes.isEmpty() && mOffer)
mMimeDataIn->setFormats(mOfferedMimeTypes);
return mMimeDataIn;
}

View File

@ -44,9 +44,11 @@
#include <QtGui/QPlatformClipboard>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
class QWaylandDisplay;
class QWaylandSelection;
class QWaylandMimeData;
struct wl_selection_offer;
class QWaylandClipboard : public QPlatformClipboard
@ -63,6 +65,8 @@ public:
void createSelectionOffer(uint32_t id);
QVariant retrieveData(const QString &mimeType, QVariant::Type type) const;
private:
static void offer(void *data,
struct wl_selection_offer *selection_offer,
@ -77,7 +81,7 @@ private:
QWaylandDisplay *mDisplay;
QWaylandSelection *mSelection;
mutable QMimeData *mMimeDataIn;
mutable QWaylandMimeData *mMimeDataIn;
QList<QWaylandSelection *> mSelections;
QStringList mOfferedMimeTypes;
struct wl_selection_offer *mOffer;