Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging
* 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging: Fix deadlocks in wayland clipboard that can occur in special scenarios.
This commit is contained in:
commit
305577936d
@ -96,7 +96,6 @@ public:
|
|||||||
QWaylandSelection(QWaylandDisplay *display, QMimeData *data);
|
QWaylandSelection(QWaylandDisplay *display, QMimeData *data);
|
||||||
~QWaylandSelection();
|
~QWaylandSelection();
|
||||||
|
|
||||||
private:
|
|
||||||
static uint32_t getTime();
|
static uint32_t getTime();
|
||||||
static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd);
|
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 void cancelled(void *data, struct wl_selection *selection);
|
||||||
@ -164,7 +163,7 @@ void QWaylandSelection::cancelled(void *data, struct wl_selection *selection)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
|
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
|
||||||
: mDisplay(display), mSelection(0), mMimeDataIn(0), mOffer(0)
|
: mDisplay(display), mMimeDataIn(0), mOffer(0)
|
||||||
{
|
{
|
||||||
clipboard = this;
|
clipboard = this;
|
||||||
}
|
}
|
||||||
@ -222,6 +221,8 @@ QVariant QWaylandClipboard::retrieveData(const QString &mimeType, QVariant::Type
|
|||||||
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
|
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
|
||||||
{
|
{
|
||||||
Q_ASSERT(mode == QClipboard::Clipboard);
|
Q_ASSERT(mode == QClipboard::Clipboard);
|
||||||
|
if (!mSelections.isEmpty())
|
||||||
|
return mSelections.last()->mMimeData;
|
||||||
if (!mMimeDataIn)
|
if (!mMimeDataIn)
|
||||||
mMimeDataIn = new QWaylandMimeData;
|
mMimeDataIn = new QWaylandMimeData;
|
||||||
mMimeDataIn->clearAll();
|
mMimeDataIn->clearAll();
|
||||||
@ -236,7 +237,7 @@ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
|
|||||||
if (!mDisplay->inputDevices().isEmpty()) {
|
if (!mDisplay->inputDevices().isEmpty()) {
|
||||||
if (!data)
|
if (!data)
|
||||||
data = new QMimeData;
|
data = new QMimeData;
|
||||||
mSelection = new QWaylandSelection(mDisplay, data);
|
mSelections.append(new QWaylandSelection(mDisplay, data));
|
||||||
} else {
|
} else {
|
||||||
qWarning("QWaylandClipboard::setMimeData: No input devices");
|
qWarning("QWaylandClipboard::setMimeData: No input devices");
|
||||||
}
|
}
|
||||||
@ -266,21 +267,27 @@ void QWaylandClipboard::offer(void *data,
|
|||||||
struct wl_selection_offer *selection_offer,
|
struct wl_selection_offer *selection_offer,
|
||||||
const char *type)
|
const char *type)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(data);
|
||||||
Q_UNUSED(selection_offer);
|
Q_UNUSED(selection_offer);
|
||||||
QWaylandClipboard *self = static_cast<QWaylandClipboard *>(data);
|
clipboard->mOfferedMimeTypes.append(QString::fromLatin1(type));
|
||||||
self->mOfferedMimeTypes.append(QString::fromLatin1(type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandClipboard::keyboardFocus(void *data,
|
void QWaylandClipboard::keyboardFocus(void *data,
|
||||||
struct wl_selection_offer *selection_offer,
|
struct wl_selection_offer *selection_offer,
|
||||||
wl_input_device *input_device)
|
wl_input_device *input_device)
|
||||||
{
|
{
|
||||||
QWaylandClipboard *self = static_cast<QWaylandClipboard *>(data);
|
Q_UNUSED(data);
|
||||||
if (!input_device) {
|
if (!input_device) {
|
||||||
wl_selection_offer_destroy(selection_offer);
|
wl_selection_offer_destroy(selection_offer);
|
||||||
self->mOffer = 0;
|
clipboard->mOffer = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->mOffer = selection_offer;
|
clipboard->mOffer = selection_offer;
|
||||||
self->emitChanged(QClipboard::Clipboard);
|
if (clipboard->mSelections.isEmpty())
|
||||||
|
QMetaObject::invokeMethod(&clipboard->mEmitter, "emitChanged", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandClipboardSignalEmitter::emitChanged()
|
||||||
|
{
|
||||||
|
clipboard->emitChanged(QClipboard::Clipboard);
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,13 @@ class QWaylandSelection;
|
|||||||
class QWaylandMimeData;
|
class QWaylandMimeData;
|
||||||
struct wl_selection_offer;
|
struct wl_selection_offer;
|
||||||
|
|
||||||
|
class QWaylandClipboardSignalEmitter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public slots:
|
||||||
|
void emitChanged();
|
||||||
|
};
|
||||||
|
|
||||||
class QWaylandClipboard : public QPlatformClipboard
|
class QWaylandClipboard : public QPlatformClipboard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -80,11 +87,11 @@ private:
|
|||||||
static void forceRoundtrip(struct wl_display *display);
|
static void forceRoundtrip(struct wl_display *display);
|
||||||
|
|
||||||
QWaylandDisplay *mDisplay;
|
QWaylandDisplay *mDisplay;
|
||||||
QWaylandSelection *mSelection;
|
|
||||||
QWaylandMimeData *mMimeDataIn;
|
QWaylandMimeData *mMimeDataIn;
|
||||||
QList<QWaylandSelection *> mSelections;
|
QList<QWaylandSelection *> mSelections;
|
||||||
QStringList mOfferedMimeTypes;
|
QStringList mOfferedMimeTypes;
|
||||||
struct wl_selection_offer *mOffer;
|
struct wl_selection_offer *mOffer;
|
||||||
|
QWaylandClipboardSignalEmitter mEmitter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QWAYLANDCLIPBOARD_H
|
#endif // QWAYLANDCLIPBOARD_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user