diff options
Diffstat (limited to 'src/plugins/platforms/wayland/qwaylandclipboard.cpp')
-rw-r--r-- | src/plugins/platforms/wayland/qwaylandclipboard.cpp | 255 |
1 files changed, 14 insertions, 241 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp index c5475016a..3ad9ed2f7 100644 --- a/src/plugins/platforms/wayland/qwaylandclipboard.cpp +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -42,218 +42,37 @@ #include "qwaylandclipboard.h" #include "qwaylanddisplay.h" #include "qwaylandinputdevice.h" -#include "qwaylandmime.h" -#include <QtGui/QPlatformNativeInterface> -#include <QtGui/QGuiApplication> -#include <QtCore/QMimeData> -#include <QtCore/QStringList> -#include <QtCore/QFile> -#include <QtCore/QtDebug> -#include <QtGui/private/qdnd_p.h> -#include <QtCore/private/qcore_unix_p.h> // for QT_READ - -static QWaylandClipboard *clipboard = 0; - -class QWaylandClipboardMimeData : 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 QWaylandClipboardMimeData::clearAll() -{ - clear(); - mFormatList.clear(); -} - -void QWaylandClipboardMimeData::setFormats(const QStringList &formatList) -{ - mFormatList = formatList; -} - -bool QWaylandClipboardMimeData::hasFormat_sys(const QString &mimeType) const -{ - return formats().contains(mimeType); -} - -QStringList QWaylandClipboardMimeData::formats_sys() const -{ - return mFormatList; -} - -QVariant QWaylandClipboardMimeData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const -{ - return clipboard->retrieveData(mimeType, type); -} - -class QWaylandSelection -{ -public: - QWaylandSelection(QWaylandDisplay *display, QMimeData *data); - ~QWaylandSelection(); - - static uint32_t getTime(); - static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd); - static void cancelled(void *data, struct wl_selection *selection); - static const struct wl_selection_listener selectionListener; - - QMimeData *mMimeData; - struct wl_selection *mSelection; -}; - -const struct wl_selection_listener QWaylandSelection::selectionListener = { - QWaylandSelection::send, - QWaylandSelection::cancelled -}; - -uint32_t QWaylandSelection::getTime() -{ - struct timeval tv; - gettimeofday(&tv, 0); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -} - -QWaylandSelection::QWaylandSelection(QWaylandDisplay *display, QMimeData *data) - : mMimeData(data), mSelection(0) -{ - struct wl_shell *shell = display->wl_shell(); - mSelection = wl_shell_create_selection(shell); - wl_selection_add_listener(mSelection, &selectionListener, this); - foreach (const QString &format, data->formats()) - wl_selection_offer(mSelection, format.toLatin1().constData()); - wl_selection_activate(mSelection, - display->inputDevices().at(0)->wl_input_device(), - getTime()); -} - -QWaylandSelection::~QWaylandSelection() -{ - if (mSelection) { - clipboard->unregisterSelection(this); - wl_selection_destroy(mSelection); - } - delete mMimeData; -} - -void QWaylandSelection::send(void *data, - struct wl_selection *selection, - const char *mime_type, - int fd) -{ - Q_UNUSED(selection); - QWaylandSelection *self = static_cast<QWaylandSelection *>(data); - QString mimeType = QString::fromLatin1(mime_type); - QByteArray content = QWaylandMimeHelper::getByteArray(self->mMimeData, mimeType); - if (!content.isEmpty()) { - QFile f; - if (f.open(fd, QIODevice::WriteOnly)) - f.write(content); - } - close(fd); -} - -void QWaylandSelection::cancelled(void *data, struct wl_selection *selection) -{ - Q_UNUSED(selection); - delete static_cast<QWaylandSelection *>(data); -} - -QWaylandClipboard *QWaylandClipboard::instance(QWaylandDisplay *display) -{ - if (!clipboard) - clipboard = new QWaylandClipboard(display); - return clipboard; -} +#include "qwaylanddataoffer.h" +#include "qwaylanddatasource.h" +#include "qwaylanddatadevicemanager.h" QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) - : mDisplay(display), mMimeDataIn(0), mOffer(0) + : mDisplay(display) { } QWaylandClipboard::~QWaylandClipboard() { - if (mOffer) - wl_selection_offer_destroy(mOffer); - delete mMimeDataIn; - qDeleteAll(mSelections); -} - -void QWaylandClipboard::unregisterSelection(QWaylandSelection *selection) -{ - mSelections.removeOne(selection); -} -void QWaylandClipboard::syncCallback(void *data, struct wl_callback *wl_callback, uint32_t time) -{ - Q_UNUSED(wl_callback); - Q_UNUSED(time); - *static_cast<bool *>(data) = true; -} -const struct wl_callback_listener QWaylandClipboard::syncCallbackListener = -{ - QWaylandClipboard::syncCallback -}; -void QWaylandClipboard::forceRoundtrip(struct wl_display *display) -{ - bool done = false; - struct wl_callback *syncCallback = wl_display_sync(display); - wl_callback_add_listener(syncCallback,&syncCallbackListener,&done); - wl_display_iterate(display, WL_DISPLAY_WRITABLE); - while (!done) - wl_display_iterate(display, WL_DISPLAY_READABLE); -} - -QVariant QWaylandClipboard::retrieveData(const QString &mimeType, QVariant::Type type) const -{ - Q_UNUSED(type); - if (mOfferedMimeTypes.isEmpty() || !mOffer) - return QVariant(); - 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 = QT_READ(pipefd[0], &buf, sizeof buf)) > 0) - content.append(buf, n); - close(pipefd[0]); - return content; } QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) { Q_ASSERT(mode == QClipboard::Clipboard); - if (!mSelections.isEmpty()) - return mSelections.last()->mMimeData; - if (!mMimeDataIn) - mMimeDataIn = new QWaylandClipboardMimeData; - mMimeDataIn->clearAll(); - if (!mOfferedMimeTypes.isEmpty() && mOffer) - mMimeDataIn->setFormats(mOfferedMimeTypes); - return mMimeDataIn; + if (!mDisplay->dndSelectionHandler()) + return 0; + + QWaylandDataSource *transfer_source = mDisplay->dndSelectionHandler()->selectionTransferSource(); + if (transfer_source) { //if we have the keyboard focus and selectionTransferSource then we own the clipboard + return transfer_source->mimeData(); + } + return mDisplay->dndSelectionHandler()->selectionTransfer(); } void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { Q_ASSERT(mode == QClipboard::Clipboard); - if (!mDisplay->inputDevices().isEmpty()) { - if (!data) - data = new QMimeData; - mSelections.append(new QWaylandSelection(mDisplay, data)); - } else { - qWarning("QWaylandClipboard::setMimeData: No input devices"); - } + if (mDisplay->dndSelectionHandler()) + mDisplay->dndSelectionHandler()->createAndSetSelectionSource(data,mode); } bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const @@ -261,49 +80,3 @@ bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } -const struct wl_selection_offer_listener QWaylandClipboard::selectionOfferListener = { - QWaylandClipboard::offer, - QWaylandClipboard::keyboardFocus -}; - -void QWaylandClipboard::createSelectionOffer(uint32_t id) -{ - mOfferedMimeTypes.clear(); - if (mOffer) - wl_selection_offer_destroy(mOffer); - mOffer = 0; - struct wl_selection_offer *offer = static_cast<struct wl_selection_offer *> - (wl_display_bind(mDisplay->wl_display(), id,&wl_selection_offer_interface)); - qDebug() << "creating selection offer"; - wl_selection_offer_add_listener(offer, &selectionOfferListener, this); -} - -void QWaylandClipboard::offer(void *data, - struct wl_selection_offer *selection_offer, - const char *type) -{ - Q_UNUSED(data); - Q_UNUSED(selection_offer); - qDebug() << "received offer"; - clipboard->mOfferedMimeTypes.append(QString::fromLatin1(type)); -} - -void QWaylandClipboard::keyboardFocus(void *data, - struct wl_selection_offer *selection_offer, - wl_input_device *input_device) -{ - Q_UNUSED(data); - if (!input_device) { - wl_selection_offer_destroy(selection_offer); - clipboard->mOffer = 0; - return; - } - clipboard->mOffer = selection_offer; - if (clipboard->mSelections.isEmpty()) - QMetaObject::invokeMethod(&clipboard->mEmitter, "emitChanged", Qt::QueuedConnection); -} - -void QWaylandClipboardSignalEmitter::emitChanged() -{ - clipboard->emitChanged(QClipboard::Clipboard); -} |