Client: Manage QMimeData lifecycle

QMimeData is created by user, it is not taken care of in qtwayland,
which will cause memory leak.

It is now handled in qtwayland that when a new QMimeData is set,
the previous QMimeData is freed.

Change-Id: Ic502021fe700c7ee10454d94f0d1868901809af7
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Tang Haixiang 2022-12-22 15:19:53 +08:00
parent 051b3ce2ee
commit 5925c3110d
4 changed files with 22 additions and 13 deletions

View File

@ -18,10 +18,15 @@ namespace QtWaylandClient {
QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display)
: mDisplay(display)
{
m_clientClipboard[QClipboard::Clipboard] = nullptr;
m_clientClipboard[QClipboard::Selection] = nullptr;
}
QWaylandClipboard::~QWaylandClipboard()
{
if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
delete m_clientClipboard[QClipboard::Clipboard];
delete m_clientClipboard[QClipboard::Selection];
}
QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
@ -33,8 +38,8 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
switch (mode) {
case QClipboard::Clipboard:
if (auto *dataDevice = seat->dataDevice()) {
if (auto *source = dataDevice->selectionSource())
return source->mimeData();
if (dataDevice->selectionSource())
return m_clientClipboard[QClipboard::Clipboard];
if (auto *offer = dataDevice->selectionOffer())
return offer->mimeData();
}
@ -42,8 +47,8 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
case QClipboard::Selection:
#if QT_CONFIG(wayland_client_primary_selection)
if (auto *selectionDevice = seat->primarySelectionDevice()) {
if (auto *source = selectionDevice->selectionSource())
return source->mimeData();
if (selectionDevice->selectionSource())
return m_clientClipboard[QClipboard::Selection];
if (auto *offer = selectionDevice->selectionOffer())
return offer->mimeData();
}
@ -68,17 +73,27 @@ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (data && data->hasFormat(plain) && !data->hasFormat(utf8))
data->setData(utf8, data->data(plain));
if (m_clientClipboard[mode]) {
if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
delete m_clientClipboard[mode];
m_clientClipboard[mode] = nullptr;
}
m_clientClipboard[mode] = data;
switch (mode) {
case QClipboard::Clipboard:
if (auto *dataDevice = seat->dataDevice()) {
dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(), data) : nullptr);
dataDevice->setSelectionSource(data ? new QWaylandDataSource(mDisplay->dndSelectionHandler(),
m_clientClipboard[QClipboard::Clipboard]) : nullptr);
emitChanged(mode);
}
break;
case QClipboard::Selection:
#if QT_CONFIG(wayland_client_primary_selection)
if (auto *selectionDevice = seat->primarySelectionDevice()) {
selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(), data) : nullptr);
selectionDevice->setSelectionSource(data ? new QWaylandPrimarySelectionSourceV1(mDisplay->primarySelectionManager(),
m_clientClipboard[QClipboard::Selection]) : nullptr);
emitChanged(mode);
}
#endif

View File

@ -45,6 +45,7 @@ public:
private:
QWaylandDisplay *mDisplay = nullptr;
QMimeData m_emptyData;
QMimeData *m_clientClipboard[2];
};
}

View File

@ -36,11 +36,6 @@ QWaylandDataSource::~QWaylandDataSource()
destroy();
}
QMimeData * QWaylandDataSource::mimeData() const
{
return m_mime_data;
}
void QWaylandDataSource::data_source_cancelled()
{
Q_EMIT cancelled();

View File

@ -38,8 +38,6 @@ public:
QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData);
~QWaylandDataSource() override;
QMimeData *mimeData() const;
Q_SIGNALS:
void cancelled();
void finished();