Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kf6-kguiaddons for openSUSE:Factory checked in at 2026-03-04 21:02:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kf6-kguiaddons (Old) and /work/SRC/openSUSE:Factory/.kf6-kguiaddons.new.561 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kf6-kguiaddons" Wed Mar 4 21:02:55 2026 rev:26 rq:1335920 version:6.23.1 Changes: -------- --- /work/SRC/openSUSE:Factory/kf6-kguiaddons/kf6-kguiaddons.changes 2026-02-16 13:05:18.344040030 +0100 +++ /work/SRC/openSUSE:Factory/.kf6-kguiaddons.new.561/kf6-kguiaddons.changes 2026-03-04 21:03:35.252391673 +0100 @@ -1,0 +2,6 @@ +Mon Mar 2 21:24:10 UTC 2026 - Christophe Marin <[email protected]> + +- Update to 6.23.1: + * clipboard: Hold mutex before dispatching any wayland events + +------------------------------------------------------------------- Old: ---- kguiaddons-6.23.0.tar.xz kguiaddons-6.23.0.tar.xz.sig New: ---- kguiaddons-6.23.1.tar.xz kguiaddons-6.23.1.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kf6-kguiaddons.spec ++++++ --- /var/tmp/diff_new_pack.lWINLo/_old 2026-03-04 21:03:36.000422591 +0100 +++ /var/tmp/diff_new_pack.lWINLo/_new 2026-03-04 21:03:36.000422591 +0100 @@ -33,10 +33,11 @@ %endif # Full KF6 version (e.g. 6.23.0) -%{!?_kf6_version: %global _kf6_version %{version}} +# %%{!?_kf6_version: %%global _kf6_version %%{version}} +%global _kf6_version 6.23.0 %bcond_without released Name: kf6-kguiaddons -Version: 6.23.0 +Version: 6.23.1 Release: 0 Summary: Utilities for graphical user interfaces License: LGPL-2.1-or-later ++++++ kguiaddons-6.23.0.tar.xz -> kguiaddons-6.23.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.23.0/CMakeLists.txt new/kguiaddons-6.23.1/CMakeLists.txt --- old/kguiaddons-6.23.0/CMakeLists.txt 2026-02-06 13:14:28.000000000 +0100 +++ new/kguiaddons-6.23.1/CMakeLists.txt 2026-03-02 16:31:07.000000000 +0100 @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.27) -set(KF_VERSION "6.23.0") # handled by release scripts +set(KF_VERSION "6.23.1") # handled by release scripts project(KGuiAddons VERSION ${KF_VERSION}) include(FeatureSummary) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kguiaddons-6.23.0/src/systemclipboard/waylandclipboard.cpp new/kguiaddons-6.23.1/src/systemclipboard/waylandclipboard.cpp --- old/kguiaddons-6.23.0/src/systemclipboard/waylandclipboard.cpp 2026-02-06 13:14:28.000000000 +0100 +++ new/kguiaddons-6.23.1/src/systemclipboard/waylandclipboard.cpp 2026-03-02 16:31:07.000000000 +0100 @@ -73,6 +73,10 @@ } // end copied +// The mutex will be held before dispatching any wayland events on our queue which could modify or use the clipboard +// it should also be held if the main thread accesses the clipboard +static QRecursiveMutex s_clipboardLock; + class DataControlDeviceManager : public QWaylandClientExtensionTemplate<DataControlDeviceManager>, public QtWayland::ext_data_control_manager_v1 { Q_OBJECT @@ -449,7 +453,6 @@ void ext_data_control_device_v1_selection(struct ::ext_data_control_offer_v1 *id) override { - QMutexLocker locker(&m_selectionLock); if (!id) { m_receivedSelection.reset(); } else { @@ -462,7 +465,6 @@ void ext_data_control_device_v1_primary_selection(struct ::ext_data_control_offer_v1 *id) override { - QMutexLocker locker(&m_primarySelectionLock); if (!id) { m_receivedPrimarySelection.reset(); } else { @@ -474,11 +476,9 @@ } private: - QRecursiveMutex m_selectionLock; std::unique_ptr<DataControlSource> m_selection; // selection set locally std::unique_ptr<DataControlOffer> m_receivedSelection; // latest selection set from externally to here - QRecursiveMutex m_primarySelectionLock; std::unique_ptr<DataControlSource> m_primarySelection; // selection set locally std::unique_ptr<DataControlOffer> m_receivedPrimarySelection; // latest selection set from externally to here friend WaylandClipboard; @@ -487,7 +487,7 @@ void DataControlDevice::setSelection(std::unique_ptr<DataControlSource> selection) { { - QMutexLocker locker(&m_selectionLock); + QMutexLocker locker(&s_clipboardLock); set_selection(selection->object()); // Note the previous selection is destroyed after the set_selection request. @@ -503,7 +503,7 @@ void DataControlDevice::setPrimarySelection(std::unique_ptr<DataControlSource> selection) { { - QMutexLocker locker(&m_primarySelectionLock); + QMutexLocker locker(&s_clipboardLock); set_primary_selection(selection->object()); // Note the previous selection is destroyed after the set_primary_selection request. @@ -552,9 +552,26 @@ void run() override { - int ret = 0; - while (ret >= 0 && !qGuiApp->closingDown()) { - ret = wl_display_dispatch_queue(m_display, m_queue); + while (!qGuiApp->closingDown()) { + while (wl_display_prepare_read_queue(m_display, m_queue) != 0) { + QMutexLocker lock(&s_clipboardLock); + wl_display_dispatch_queue_pending(m_display, m_queue); + } + wl_display_flush(m_display); + + struct pollfd pfd[1]; + pfd[0].fd = wl_display_get_fd(m_display); + pfd[0].events = POLLIN; + int pollRet = poll(pfd, 1, -1); + if (pollRet < 0 && errno != EPIPE) { + wl_display_cancel_read(m_display); + break; + } else { + wl_display_read_events(m_display); + } + + QMutexLocker lock(&s_clipboardLock); + wl_display_dispatch_queue_pending(m_display, m_queue); } } wl_callback *m_callback = nullptr; @@ -664,11 +681,11 @@ } if (mode == QClipboard::Clipboard) { - QMutexLocker locker(&m_device->m_selectionLock); + QMutexLocker locker(&s_clipboardLock); m_device->set_selection(nullptr); m_device->m_selection.reset(); } else if (mode == QClipboard::Selection) { - QMutexLocker locker(&m_device->m_primarySelectionLock); + QMutexLocker locker(&s_clipboardLock); m_device->set_primary_selection(nullptr); m_device->m_primarySelection.reset(); } @@ -681,20 +698,18 @@ } // WaylandClipboard owns the mimedata, but the caller can read it until the next event loop runs. - auto lockWithUnlockLater = [this](QRecursiveMutex &mutex) { - mutex.lock(); - QTimer::singleShot(0, this, [&mutex, guard = QPointer<DataControlDevice>(m_device.get())] { - if (!guard) { - return; - } - mutex.unlock(); + auto lockWithUnlockLater = [this]() { + s_clipboardLock.lock(); + QTimer::singleShot(0, this, [] { + s_clipboardLock.unlock(); }); }; // return our locally set selection if it's not cancelled to avoid copying data to ourselves if (mode == QClipboard::Clipboard) { - QMutexLocker lock(&m_device->m_selectionLock); + QMutexLocker lock(&s_clipboardLock); if (m_device->selection()) { + lockWithUnlockLater(); return m_device->selection(); } @@ -702,11 +717,13 @@ if (QGuiApplication::clipboard()->ownsClipboard()) { return QGuiApplication::clipboard()->mimeData(mode); } - lockWithUnlockLater(m_device->m_selectionLock); + + lockWithUnlockLater(); return m_device->receivedSelection(); } else if (mode == QClipboard::Selection) { - QMutexLocker lock(&m_device->m_primarySelectionLock); + QMutexLocker lock(&s_clipboardLock); if (m_device->primarySelection()) { + lockWithUnlockLater(); return m_device->primarySelection(); } @@ -715,7 +732,7 @@ return QGuiApplication::clipboard()->mimeData(mode); } - lockWithUnlockLater(m_device->m_primarySelectionLock); + lockWithUnlockLater(); return m_device->receivedPrimarySelection(); } return nullptr;
