summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTang Haixiang <tanghaixiang@uniontech.com>2022-12-22 15:19:53 +0800
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-06-08 07:22:08 +0000
commitd8125d85f3122ae205ef36dd2039c800ea67bff5 (patch)
treec9b7685382bf42ef5996e8371ba4b5028a868ba3
parentd3f4b3be5157f7a095b6176c98787065ae4ed4ec (diff)
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. This is a backport of commit 3af40c6c42703a65656fdd3322183abb2905e44d which was submitted to dev / 6.6. In hindsight, it was decided it should have also gone to patch releases, hence this backport. Pick-to: 5.15 6.2 Change-Id: Ic502021fe700c7ee10454d94f0d1868901809af7 Reviewed-by: David Edmundson <davidedmundson@kde.org>
-rw-r--r--src/client/qwaylandclipboard.cpp27
-rw-r--r--src/client/qwaylandclipboard_p.h1
-rw-r--r--src/client/qwaylanddatasource.cpp5
-rw-r--r--src/client/qwaylanddatasource_p.h2
4 files changed, 22 insertions, 13 deletions
diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp
index d3566244b..df6cf5d2b 100644
--- a/src/client/qwaylandclipboard.cpp
+++ b/src/client/qwaylandclipboard.cpp
@@ -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
diff --git a/src/client/qwaylandclipboard_p.h b/src/client/qwaylandclipboard_p.h
index 655620bda..414e3dc71 100644
--- a/src/client/qwaylandclipboard_p.h
+++ b/src/client/qwaylandclipboard_p.h
@@ -45,6 +45,7 @@ public:
private:
QWaylandDisplay *mDisplay = nullptr;
QMimeData m_emptyData;
+ QMimeData *m_clientClipboard[2];
};
}
diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp
index 093c40f2f..966d5ef7f 100644
--- a/src/client/qwaylanddatasource.cpp
+++ b/src/client/qwaylanddatasource.cpp
@@ -36,11 +36,6 @@ QWaylandDataSource::~QWaylandDataSource()
destroy();
}
-QMimeData * QWaylandDataSource::mimeData() const
-{
- return m_mime_data;
-}
-
void QWaylandDataSource::data_source_cancelled()
{
Q_EMIT cancelled();
diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h
index 0ce09a409..a4b317c26 100644
--- a/src/client/qwaylanddatasource_p.h
+++ b/src/client/qwaylanddatasource_p.h
@@ -38,8 +38,6 @@ public:
QWaylandDataSource(QWaylandDataDeviceManager *dataDeviceManager, QMimeData *mimeData);
~QWaylandDataSource() override;
- QMimeData *mimeData() const;
-
Q_SIGNALS:
void cancelled();
void finished();