ALT Linux Bugzilla
– Attachment 20993 Details for
Bug 58423
Битые скриншоты в буфере обмена при быстром копировании из Spectacle
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
Обновлённый патч
alt-fix-multiple-clipboard-insertions.patch (text/plain), 5.13 KB, created by
Жора Змейкин
on 2026-03-29 09:19:55 MSK
(
hide
)
Description:
Обновлённый патч
Filename:
MIME Type:
Creator:
Жора Змейкин
Created:
2026-03-29 09:19:55 MSK
Size:
5.13 KB
patch
obsolete
>--- a/src/systemclipboard/waylandclipboard.cpp 2026-03-27 21:21:27.238356306 +0300 >+++ b/src/systemclipboard/waylandclipboard.cpp 2026-03-27 21:23:05.729935169 +0300 >@@ -16,6 +16,7 @@ > #include <QPointer> > #include <QThread> > #include <QTimer> >+#include <QQueue> > #include <QWaylandClientExtension> > #include <QWindow> > #include <QtWaylandClientVersion> >@@ -320,6 +321,7 @@ > > Q_SIGNALS: > void cancelled(); >+ void dataSendingCompleted(); > > protected: > void ext_data_control_source_v1_send(const QString &mime_type, int32_t fd) override; >@@ -394,6 +396,8 @@ > break; > } > close(fd); >+ >+ Q_EMIT dataSendingCompleted(); > } > > void DataControlSource::ext_data_control_source_v1_cancelled() >@@ -578,6 +582,108 @@ > wl_display *m_display = nullptr; > }; > >+class ClipboardProcessingQueue : public QObject >+{ >+ Q_OBJECT >+public: >+ explicit ClipboardProcessingQueue(WaylandClipboard &wclip, QObject *parent = nullptr); >+ ~ClipboardProcessingQueue(); >+ >+ void addMimeData(QMimeData *data); >+ void stop(); >+ >+private Q_SLOTS: >+ void processNext(); >+ >+private: >+ QThread m_th; >+ QMutex m_mtx; >+ QQueue<QMimeData*> m_queue; >+ WaylandClipboard &m_wclip; >+ bool m_stopped = false; >+ bool m_processing = false; >+ QEventLoop *m_waitLoop = nullptr; >+}; >+ >+ClipboardProcessingQueue::ClipboardProcessingQueue(WaylandClipboard &wclip, QObject *parent) >+ : QObject(parent) >+ , m_wclip(wclip) >+{ >+ moveToThread(&m_th); >+ m_th.start(); >+} >+ >+ClipboardProcessingQueue::~ClipboardProcessingQueue() >+{ >+ if (m_th.isRunning()) { >+ m_th.quit(); >+ m_th.wait(); >+ } >+} >+ >+void ClipboardProcessingQueue::addMimeData(QMimeData *data) >+{ >+ QMutexLocker locker(&m_mtx); >+ m_queue.enqueue(data); >+ if (!m_processing) { >+ QMetaObject::invokeMethod(this, "processNext", Qt::QueuedConnection); >+ } >+} >+ >+void ClipboardProcessingQueue::stop() >+{ >+ QMutexLocker locker(&m_mtx); >+ m_stopped = true; >+ >+ if (m_waitLoop && m_waitLoop->isRunning()) { >+ QMetaObject::invokeMethod(this, [this]{ >+ m_waitLoop->quit(); >+ }, Qt::QueuedConnection); >+ } >+} >+ >+void ClipboardProcessingQueue::processNext() >+{ >+ if (m_stopped) { >+ return; >+ } >+ >+ QMimeData *mime = nullptr; >+ { >+ QMutexLocker locker(&m_mtx); >+ if (m_queue.isEmpty() || m_processing) { >+ return; >+ } >+ mime = m_queue.dequeue(); >+ m_processing = true; >+ } >+ >+ if (mime) { >+ auto &device = m_wclip.m_device; >+ auto &manager = m_wclip.m_manager; >+ auto source = std::make_unique<DataControlSource>(manager->create_data_source(), mime); >+ source->moveToThread(m_wclip.m_thread.get()); >+ >+ auto *sourcePtr = source.get(); >+ device->setSelection(std::move(source)); >+ >+ QEventLoop loop; >+ m_waitLoop = &loop; >+ connect(sourcePtr, &DataControlSource::dataSendingCompleted, &loop, &QEventLoop::quit); >+ connect(sourcePtr, &DataControlSource::cancelled, &loop, &QEventLoop::quit); >+ QTimer::singleShot(5000, &loop, &QEventLoop::quit); >+ loop.exec(); >+ m_waitLoop = nullptr; >+ } >+ >+ { >+ QMutexLocker locker(&m_mtx); >+ m_processing = false; >+ } >+ >+ QMetaObject::invokeMethod(this, "processNext", Qt::QueuedConnection); >+} >+ > WaylandClipboard::WaylandClipboard(QObject *parent) > : KSystemClipboard(parent) > , m_manager(new DataControlDeviceManager) >@@ -623,9 +729,12 @@ > connect(m_device.get(), &DataControlDevice::primarySelectionChanged, this, [this]() { > Q_EMIT changed(QClipboard::Selection); > }); >+ >+ m_dataQueue.reset(new ClipboardProcessingQueue(*this)); > m_thread->start(); > > } else { >+ m_dataQueue.reset(); > m_device.reset(); > m_thread->wait(); > m_thread.reset(); >@@ -637,6 +746,9 @@ > > WaylandClipboard::~WaylandClipboard() > { >+ if (m_dataQueue) { >+ m_dataQueue->stop(); >+ } > if (m_thread && m_thread->isRunning()) { > m_thread->syncQueue(); > m_thread->wait(); >@@ -664,6 +776,12 @@ > return; > } > >+ // Use only for clipboard insertion and if mime data contains an image >+ if (mode == QClipboard::Clipboard && mime->hasImage()) { >+ m_dataQueue->addMimeData(mime); >+ return; >+ } >+ > auto source = std::make_unique<DataControlSource>(m_manager->create_data_source(), mime); > source->moveToThread(m_thread.get()); > if (mode == QClipboard::Clipboard) { >--- a/src/systemclipboard/waylandclipboard_p.h 2026-03-27 21:21:27.240356358 +0300 >+++ b/src/systemclipboard/waylandclipboard_p.h 2026-03-27 21:23:20.559323455 +0300 >@@ -14,6 +14,7 @@ > class DataControlDevice; > class DataControlDeviceManager; > class ClipboardThread; >+class ClipboardProcessingQueue; > > class WaylandClipboard : public KSystemClipboard > { >@@ -32,6 +33,9 @@ > std::unique_ptr<ClipboardThread> m_thread; > std::unique_ptr<DataControlDeviceManager> m_manager; > std::unique_ptr<DataControlDevice> m_device; >+ std::unique_ptr<ClipboardProcessingQueue> m_dataQueue; >+ >+ friend ClipboardProcessingQueue; > }; > > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 58423
: 20993