Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libdbusmenu-lxqt for openSUSE:Factory checked in at 2025-04-22 17:26:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libdbusmenu-lxqt (Old) and /work/SRC/openSUSE:Factory/.libdbusmenu-lxqt.new.30101 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libdbusmenu-lxqt" Tue Apr 22 17:26:42 2025 rev:3 rq:1270859 version:0.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libdbusmenu-lxqt/libdbusmenu-lxqt.changes 2024-11-11 13:46:44.663377796 +0100 +++ /work/SRC/openSUSE:Factory/.libdbusmenu-lxqt.new.30101/libdbusmenu-lxqt.changes 2025-04-22 17:27:06.544125014 +0200 @@ -1,0 +2,8 @@ +Thu Apr 17 23:49:20 UTC 2025 - Shawn Dunn <sfal...@opensuse.org> + +- Update to version 0.3.0: + * A workaround is added for a Qt crash on reloading menus + * Code Cleanup +- Removed Group: declarations, no longer used + +------------------------------------------------------------------- Old: ---- libdbusmenu-lxqt-0.2.0.tar.xz libdbusmenu-lxqt-0.2.0.tar.xz.asc New: ---- libdbusmenu-lxqt-0.3.0.tar.xz libdbusmenu-lxqt-0.3.0.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libdbusmenu-lxqt.spec ++++++ --- /var/tmp/diff_new_pack.L0aBNL/_old 2025-04-22 17:27:07.236154055 +0200 +++ /var/tmp/diff_new_pack.L0aBNL/_new 2025-04-22 17:27:07.236154055 +0200 @@ -18,17 +18,15 @@ %define _ver 0 Name: libdbusmenu-lxqt -Version: 0.2.0 +Version: 0.3.0 Release: 0 Summary: A Qt implementation of the DBusMenu protocol License: LGPL-2.0-or-later -Group: System/Libraries URL: https://github.com/lxqt/libdbusmenu-lxqt Source0: %{url}/releases/download/%{version}/%{name}-%{version}.tar.xz Source1: %{url}/releases/download/%{version}/%{name}-%{version}.tar.xz.asc Source2: %{name}.keyring -BuildRequires: cmake >= 3.18.0 -#uildRequires: libqjson-devel +BuildRequires: cmake >= 3.5.0 BuildRequires: cmake(Qt6Core) >= 6.3.0 BuildRequires: gcc-c++ BuildRequires: cmake(Qt6DBus) ++++++ libdbusmenu-lxqt-0.2.0.tar.xz -> libdbusmenu-lxqt-0.3.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/CHANGELOG new/libdbusmenu-lxqt-0.3.0/CHANGELOG --- old/libdbusmenu-lxqt-0.2.0/CHANGELOG 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/CHANGELOG 2025-04-17 10:54:29.000000000 +0200 @@ -1,3 +1,9 @@ +libdbusmenu-lxqt-0.3.0 / 2025-04-17 +=================================== + * Workaround for a Qt crash on reloading menus. + * Got rid of `Q_FOREACH`. + * Fixed tests after recent changes. + libdbusmenu-lxqt-0.2.0 / 2024-11-05 =================================== * Stop checking for `QIcon::name()` existence. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/CMakeLists.txt new/libdbusmenu-lxqt-0.3.0/CMakeLists.txt --- old/libdbusmenu-lxqt-0.2.0/CMakeLists.txt 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/CMakeLists.txt 2025-04-17 10:54:29.000000000 +0200 @@ -8,7 +8,7 @@ # Versions ## Package version set(dbusmenu_lxqt_VERSION_MAJOR 0) -set(dbusmenu_lxqt_VERSION_MINOR 2) +set(dbusmenu_lxqt_VERSION_MINOR 3) set(dbusmenu_lxqt_VERSION_PATCH 0) set(dbusmenu_lxqt_VERSION ${dbusmenu_lxqt_VERSION_MAJOR}.${dbusmenu_lxqt_VERSION_MINOR}.${dbusmenu_lxqt_VERSION_PATCH}) @@ -17,7 +17,7 @@ set(dbusmenu_lxqt_lib_SOVERSION 0) ### Bump this one when the API is extended in a binary-compatible way -set(dbusmenu_lxqt_lib_API_VERSION 2) +set(dbusmenu_lxqt_lib_API_VERSION 3) ### Bump this one when changes do not extend the API set(dbusmenu_lxqt_lib_PATCH_VERSION 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenuexporter.cpp new/libdbusmenu-lxqt-0.3.0/src/dbusmenuexporter.cpp --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenuexporter.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenuexporter.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -61,7 +61,8 @@ return; } new DBusMenu(menu, q, parentId); - Q_FOREACH(QAction *action, menu->actions()) { + const auto mActions = menu->actions(); + for (QAction *action : mActions) { addAction(action, parentId); } } @@ -157,7 +158,8 @@ item->properties = m_dbusObject->getProperties(id, propertyNames); if (depth != 0 && menu) { - Q_FOREACH(QAction *action, menu->actions()) { + const auto mActions = menu->actions(); + for (QAction *action : mActions) { int actionId = m_idForAction.value(action, -1); if (actionId == -1) { DMWARNING << "No id for action"; @@ -367,7 +369,7 @@ DBusMenuItemList updatedList; DBusMenuItemKeysList removedList; - Q_FOREACH(int id, d->m_itemUpdatedIds) { + for (int id : std::as_const(d->m_itemUpdatedIds)) { QAction *action = d->m_actionForId.value(id); if (!action) { // Action does not exist anymore @@ -444,7 +446,7 @@ void DBusMenuExporter::doEmitLayoutUpdated() { // Collapse separators for all updated menus - Q_FOREACH(int id, d->m_layoutUpdatedIds) { + for (int id : std::as_const(d->m_layoutUpdatedIds)) { QMenu* menu = d->menuForId(id); if (menu && menu->separatorsCollapsible()) { d->collapseSeparators(menu); @@ -453,7 +455,7 @@ // Tell the world about the update if (d->m_emittedLayoutUpdatedOnce) { - Q_FOREACH(int id, d->m_layoutUpdatedIds) { + for (int id : std::as_const(d->m_layoutUpdatedIds)) { d->m_dbusObject->LayoutUpdated(d->m_revision, id); } } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenuexporterdbus_p.cpp new/libdbusmenu-lxqt-0.3.0/src/dbusmenuexporterdbus_p.cpp --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenuexporterdbus_p.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenuexporterdbus_p.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -94,7 +94,7 @@ return all; } else { QVariantMap map; - Q_FOREACH(const QString &name, names) { + for (const QString &name : names) { QVariant value = all.value(name); if (value.isValid()) { map.insert(name, value); @@ -107,7 +107,7 @@ DBusMenuItemList DBusMenuExporterDBus::GetGroupProperties(const QList<int> &ids, const QStringList &names) { DBusMenuItemList list; - Q_FOREACH(int id, ids) { + for (int id : ids) { DBusMenuItem item; item.id = id; item.properties = getProperties(item.id, names); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenuimporter.cpp new/libdbusmenu-lxqt-0.3.0/src/dbusmenuimporter.cpp --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenuimporter.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenuimporter.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -52,6 +52,7 @@ static const int ABOUT_TO_SHOW_TIMEOUT = 3000; static const int REFRESH_TIMEOUT = 4000; +static const int LAYOUT_UPDATE_TIMEOUT = 2000; static const char *DBUSMENU_PROPERTY_ID = "_dbusmenu_id"; static const char *DBUSMENU_PROPERTY_ICON_NAME = "_dbusmenu_icon_name"; @@ -73,6 +74,25 @@ return titleAction; } +Menu::Menu(QWidget *parent) : QMenu(parent), blockEvents(false) {} + +bool Menu::event(QEvent *e) { + if (blockEvents + // These events are dangerous while actions are being replaced: + && (e->type() == QEvent::Timer || + e->type() == QEvent::MouseMove || + e->type() == QEvent::MouseButtonPress || + e->type() == QEvent::MouseButtonRelease || + e->type() == QEvent::KeyPress || + e->type() == QEvent::KeyRelease || + e->type() == QEvent::Leave || + e->type() == QEvent::Enter)) { + e->accept(); + return true; + } + return QMenu::event(e); +} + class DBusMenuImporterPrivate { public: @@ -84,6 +104,7 @@ ActionForId m_actionForId; QSignalMapper m_mapper; QTimer *m_pendingLayoutUpdateTimer; + bool m_refreshing; QSet<int> m_idsRefreshedByAboutToShow; QSet<int> m_pendingLayoutUpdates; @@ -98,6 +119,9 @@ DMDEBUG << "Starting refresh chrono for id" << id; sChrono.start(); #endif + + m_refreshing = true; + QDBusPendingCall call = m_interface->asyncCall("GetLayout", id, 1, QStringList()); QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, q); watcher->setProperty(DBUSMENU_PROPERTY_ID, id); @@ -171,7 +195,7 @@ */ void updateAction(QAction *action, const QVariantMap &map, const QStringList &requestedProperties) { - Q_FOREACH(const QString &key, requestedProperties) { + for (const QString &key : requestedProperties) { updateActionProperty(action, key, map.value(key)); } } @@ -336,6 +360,7 @@ d->m_interface = new QDBusInterface(service, path, DBUSMENU_INTERFACE, QDBusConnection::sessionBus(), this); d->m_menu = 0; d->m_mustEmitMenuUpdated = false; + d->m_refreshing = false; d->m_type = type; @@ -343,6 +368,18 @@ d->m_pendingLayoutUpdateTimer = new QTimer(this); d->m_pendingLayoutUpdateTimer->setSingleShot(true); + /** + * WARNING: To avoid a Qt bug triggered by "QMenu::timerEvent" on refreshing + * a menu that has a visible submenu, a minimum interval of two seconds is + * set between two consecutive updates for the sake of certainty. + * + * With intervals shorter than one second, the pointer "d->currentAction" in + * QMenu's code may become dangling and cause a crash. + * + * To be on the safe side, we also use "Menu", instead of QMenu, to block some + * events during updates, especially the timer events. + */ + d->m_pendingLayoutUpdateTimer->setInterval(LAYOUT_UPDATE_TIMEOUT); connect(d->m_pendingLayoutUpdateTimer, SIGNAL(timeout()), SLOT(processPendingLayoutUpdates())); // For some reason, using QObject::connect() does not work but @@ -371,17 +408,19 @@ if (d->m_idsRefreshedByAboutToShow.remove(parentId)) { return; } - d->m_pendingLayoutUpdates << parentId; - if (!d->m_pendingLayoutUpdateTimer->isActive()) { + if (!d->m_pendingLayoutUpdates.contains(parentId)) { + d->m_pendingLayoutUpdates << parentId; + } + if (!d->m_pendingLayoutUpdateTimer->isActive() && !d->m_refreshing) { d->m_pendingLayoutUpdateTimer->start(); } } void DBusMenuImporter::processPendingLayoutUpdates() { - QSet<int> ids = d->m_pendingLayoutUpdates; + const QSet<int> ids = d->m_pendingLayoutUpdates; d->m_pendingLayoutUpdates.clear(); - Q_FOREACH(int id, ids) { + for (int id : ids) { d->refresh(id); } } @@ -396,7 +435,7 @@ void DBusMenuImporterPrivate::slotItemsPropertiesUpdated(const DBusMenuItemList &updatedList, const DBusMenuItemKeysList &removedList) { - Q_FOREACH(const DBusMenuItem &item, updatedList) { + for (const DBusMenuItem &item : updatedList) { QAction *action = m_actionForId.value(item.id); if (!action) { // We don't know this action. It probably is in a menu we haven't fetched yet. @@ -411,14 +450,14 @@ } } - Q_FOREACH(const DBusMenuItemKeys &item, removedList) { + for (const DBusMenuItemKeys &item : removedList) { QAction *action = m_actionForId.value(item.id); if (!action) { // We don't know this action. It probably is in a menu we haven't fetched yet. continue; } - Q_FOREACH(const QString &key, item.properties) { + for (const QString &key : std::as_const(item.properties)) { updateActionProperty(action, key, QVariant()); } } @@ -439,6 +478,7 @@ QDBusPendingReply<uint, DBusMenuLayoutItem> reply = *watcher; if (!reply.isValid()) { DMWARNING << reply.error().message(); + d->m_refreshing = false; return; } @@ -450,12 +490,26 @@ QMenu *menu = d->menuForId(parentId); if (!menu) { DMWARNING << "No menu for id" << parentId; + d->m_refreshing = false; return; } + // Block some menu events while actions are reloaded. + auto m = qobject_cast<Menu*>(menu); + if (m) { + m->blockEvents = true; + } + + // Try to restore the active action, such that a visible submenu + // will be reopened after reloading actions. + menu->setUpdatesEnabled(false); + int activeIndex = menu->actions().indexOf(menu->activeAction()); + QAction *activeAction = nullptr; + int index = 0; + menu->clear(); - Q_FOREACH(const DBusMenuLayoutItem &dbusMenuItem, rootItem.children) { + for (const DBusMenuLayoutItem &dbusMenuItem : std::as_const(rootItem.children)) { QAction *action = d->createAction(dbusMenuItem.id, dbusMenuItem.properties, menu); DBusMenuImporterPrivate::ActionForId::Iterator it = d->m_actionForId.find(dbusMenuItem.id); if (it == d->m_actionForId.end()) { @@ -470,11 +524,45 @@ &d->m_mapper, SLOT(map())); d->m_mapper.setMapping(action, dbusMenuItem.id); - if( action->menu() ) - { - d->refresh( dbusMenuItem.id )->waitForFinished(); + if (index == activeIndex) { + if (action->isEnabled() && !action->isSeparator()) { + activeAction = action; + } + else { + ++activeIndex; + } + } + ++index; + + // NOTE: The new submenus will be refreshed in "slotMenuAboutToShow" on showing. + // So, a recursive call "d->refresh(dbusMenuItem.id)" is not needed here. + } + + if (activeIndex > -1 && !activeAction) { // try to activate the last action + const auto acts = menu->actions(); + for (int i = acts.size() -1; i >= 0; --i) { + auto act = acts.at(i); + if (act->isEnabled() && !act->isSeparator()) { + activeAction = act; + break; + } } } + if (activeAction) { + menu->setActiveAction(activeAction); + } + menu->setUpdatesEnabled(true); + + if (m) { + m->blockEvents = false; + } + + // The next update of pending layouts, if any. + d->m_refreshing = false; + if (d->m_pendingLayoutUpdateTimer) { + d->m_pendingLayoutUpdateTimer->start(); + } + #ifdef BENCHMARK DMDEBUG << "- Menu filled:" << sChrono.elapsed() << "ms"; #endif @@ -575,7 +663,7 @@ QMenu *DBusMenuImporter::createMenu(QWidget *parent) { - return new QMenu(parent); + return new Menu(parent); // use "Menu" for our workaround } QIcon DBusMenuImporter::iconForName(const QString &/*name*/) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenuimporter.h new/libdbusmenu-lxqt-0.3.0/src/dbusmenuimporter.h --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenuimporter.h 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenuimporter.h 2025-04-17 10:54:29.000000000 +0200 @@ -23,6 +23,7 @@ // Qt #include <QtCore/QObject> +#include <QMenu> // Local #include <dbusmenu_export.h> @@ -32,10 +33,21 @@ class QDBusPendingCallWatcher; class QDBusVariant; class QIcon; -class QMenu; +class QEvent; class DBusMenuImporterPrivate; +// For working around a crash triggered by "QMenu::timerEvent" +class Menu : public QMenu { + Q_OBJECT +public: + Menu(QWidget *parent = nullptr); + bool blockEvents; + +protected: + bool event(QEvent *e) override; +}; + /** * Determine whether internal method calls should allow the Qt event loop * to execute or not diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenushortcut_p.cpp new/libdbusmenu-lxqt-0.3.0/src/dbusmenushortcut_p.cpp --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenushortcut_p.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenushortcut_p.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -60,8 +60,8 @@ { QString string = sequence.toString(); DBusMenuShortcut shortcut; - QStringList tokens = string.split(", "); - Q_FOREACH(QString token, tokens) { + const QStringList tokens = string.split(", "); + for (QString token : tokens) { // Hack: Qt::CTRL | Qt::Key_Plus is turned into the string "Ctrl++", // but we don't want the call to token.split() to consider the // second '+' as a separator so we replace it with its final value. @@ -76,7 +76,7 @@ QKeySequence DBusMenuShortcut::toKeySequence() const { QStringList tmp; - Q_FOREACH(const QStringList& keyTokens_, *this) { + for (const QStringList& keyTokens_ : std::as_const(*this)) { QStringList keyTokens = keyTokens_; processKeyTokens(&keyTokens, DM_COLUMN, QT_COLUMN); tmp << keyTokens.join(QLatin1String("+")); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/src/dbusmenutypes_p.cpp new/libdbusmenu-lxqt-0.3.0/src/dbusmenutypes_p.cpp --- old/libdbusmenu-lxqt-0.2.0/src/dbusmenutypes_p.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/src/dbusmenutypes_p.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -68,7 +68,7 @@ argument.beginStructure(); argument << obj.id << obj.properties; argument.beginArray(qMetaTypeId<QDBusVariant>()); - Q_FOREACH(const DBusMenuLayoutItem& child, obj.children) { + for (const DBusMenuLayoutItem& child : std::as_const(obj.children)) { argument << QDBusVariant(QVariant::fromValue<DBusMenuLayoutItem>(child)); } argument.endArray(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/tests/dbusmenuexportertest.cpp new/libdbusmenu-lxqt-0.3.0/tests/dbusmenuexportertest.cpp --- old/libdbusmenu-lxqt-0.2.0/tests/dbusmenuexportertest.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/tests/dbusmenuexportertest.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -352,8 +352,8 @@ QCOMPARE(spy.count(), 1); QSet<int> updatedIds; { - QVariantList lst = spy.takeFirst().at(0).toList(); - Q_FOREACH(QVariant variant, lst) { + const QVariantList lst = spy.takeFirst().at(0).toList(); + for (const QVariant &variant : lst) { updatedIds << variant.toInt(); } } @@ -392,10 +392,10 @@ // Check items are checkmark, not radio item = list.takeFirst(); QCOMPARE(item.properties.value("toggle-type").toString(), QString("checkmark")); - int a1Id = item.id; + //int a1Id = item.id; item = list.takeFirst(); QCOMPARE(item.properties.value("toggle-type").toString(), QString("checkmark")); - int a2Id = item.id; + //int a2Id = item.id; } void DBusMenuExporterTest::testClickDeletedAction() @@ -459,7 +459,7 @@ // Create a menu containing an action with a shortcut QMenu inputMenu; QVERIFY(QDBusConnection::sessionBus().registerService(TEST_SERVICE)); - DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); + DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); Q_UNUSED(exporter) QAction *a1 = inputMenu.addAction("a1"); a1->setShortcut(Qt::CTRL | Qt::Key_A); @@ -482,7 +482,7 @@ DBusMenuLayoutItemList list = getChildren(&iface, 0, propertyNames); QCOMPARE(list.count(), actionList.count()); - Q_FOREACH(const QAction* action, actionList) { + for (const QAction* action : std::as_const(actionList)) { DBusMenuLayoutItem item = list.takeFirst(); if (action->shortcut().isEmpty()) { QVERIFY(!item.properties.contains("shortcut")); @@ -501,18 +501,20 @@ // Create a menu containing two actions QMenu inputMenu; QVERIFY(QDBusConnection::sessionBus().registerService(TEST_SERVICE)); - DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); + DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); Q_UNUSED(exporter) - QAction *a1 = inputMenu.addAction("a1"); - QAction *a2 = inputMenu.addAction("a2"); + inputMenu.addAction("a1"); + inputMenu.addAction("a2"); // Check exporter is on DBus QDBusInterface iface(TEST_SERVICE, TEST_OBJECT_PATH); QVERIFY2(iface.isValid(), qPrintable(iface.lastError().message())); + const auto iActions = inputMenu.actions(); + // Get item ids DBusMenuLayoutItemList list = getChildren(&iface, 0, QStringList()); - QCOMPARE(list.count(), inputMenu.actions().count()); + QCOMPARE(list.count(), iActions.count()); int id1 = list.at(0).id; int id2 = list.at(1).id; @@ -524,9 +526,9 @@ DBusMenuItemList groupPropertiesList = reply.value(); // Check the info we received - QCOMPARE(groupPropertiesList.count(), inputMenu.actions().count()); + QCOMPARE(groupPropertiesList.count(), iActions.count()); - Q_FOREACH(const QAction* action, inputMenu.actions()) { + for (const QAction* action : iActions) { DBusMenuItem item = groupPropertiesList.takeFirst(); QCOMPARE(item.properties.value("label").toString(), action->text()); } @@ -569,9 +571,9 @@ static int trackCount(QMenu* menu) { - QList<QObject*> lst = menu->findChildren<QObject*>(); + const QList<QObject*> lst = menu->findChildren<QObject*>(); int count = 0; - Q_FOREACH(QObject* child, lst) { + for (QObject* child : lst) { if (qstrcmp(child->metaObject()->className(), "DBusMenu") == 0) { ++count; } @@ -587,7 +589,7 @@ // submenu should not have more than one DBusMenu child object. QMenu mainMenu; QVERIFY(QDBusConnection::sessionBus().registerService(TEST_SERVICE)); - DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &mainMenu); + DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &mainMenu); Q_UNUSED(exporter) QMenu* subMenu = new QMenu("File"); subMenu->addAction("a1"); @@ -631,7 +633,8 @@ static bool hasInternalDBusMenuObject(QMenu* menu) { - Q_FOREACH(QObject* obj, menu->children()) { + const auto mChildren = menu->children(); + for (QObject* obj : mChildren) { if (obj->inherits("DBusMenu")) { return true; } @@ -647,7 +650,7 @@ QVERIFY(QDBusConnection::sessionBus().registerService(TEST_SERVICE)); DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); - QAction *a1 = inputMenu.addAction("a1"); + inputMenu.addAction("a1"); QVERIFY2(hasInternalDBusMenuObject(&inputMenu), "Test setup failed"); delete exporter; QVERIFY(!hasInternalDBusMenuObject(&inputMenu)); @@ -677,7 +680,7 @@ QMenu inputMenu; QVERIFY(QDBusConnection::sessionBus().registerService(TEST_SERVICE)); - DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); + DBusMenuExporter *exporter = new DBusMenuExporter(TEST_OBJECT_PATH, &inputMenu); Q_UNUSED(exporter) if (input.isEmpty()) { // Pretend there was an action so that doEmitLayoutUpdated() is called @@ -686,7 +689,7 @@ delete inputMenu.addAction("dummy"); } - Q_FOREACH(QChar ch, input) { + for (QChar ch : std::as_const(input)) { if (ch == '-') { inputMenu.addSeparator(); } else { @@ -702,11 +705,11 @@ // Get exported menu info QStringList propertyNames = QStringList(); - DBusMenuLayoutItemList list = getChildren(&iface, /*parentId=*/0, propertyNames); + const DBusMenuLayoutItemList list = getChildren(&iface, /*parentId=*/0, propertyNames); // Recreate a menu string from the item list QString output; - Q_FOREACH(const DBusMenuLayoutItem& item, list) { + for (const DBusMenuLayoutItem& item : list) { QVariantMap properties = item.properties; if (properties.contains("visible") && !properties.value("visible").toBool()) { continue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/tests/dbusmenuimportertest.cpp new/libdbusmenu-lxqt-0.3.0/tests/dbusmenuimportertest.cpp --- old/libdbusmenu-lxqt-0.2.0/tests/dbusmenuimportertest.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/tests/dbusmenuimportertest.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -58,7 +58,7 @@ void DBusMenuImporterTest::testStandardItem() { QMenu inputMenu; - QAction *action = inputMenu.addAction("Test"); + inputMenu.addAction("Test"); DBusMenuExporter exporter(TEST_OBJECT_PATH, &inputMenu); DBusMenuImporter importer(TEST_SERVICE, TEST_OBJECT_PATH); @@ -73,7 +73,7 @@ void DBusMenuImporterTest::testAddingNewItem() { QMenu inputMenu; - QAction *action = inputMenu.addAction("Test"); + inputMenu.addAction("Test"); DBusMenuExporter exporter(TEST_OBJECT_PATH, &inputMenu); DBusMenuImporter importer(TEST_SERVICE, TEST_OBJECT_PATH); @@ -82,7 +82,8 @@ QCOMPARE(outputMenu->actions().count(), inputMenu.actions().count()); inputMenu.addAction("Test2"); - QTest::qWait(500); + inputMenu.addAction("Test3"); + QTest::qWait(2000); // see "LAYOUT_UPDATE_TIMEOUT" in the c-tor of "DBusMenuImporter" QCOMPARE(outputMenu->actions().count(), inputMenu.actions().count()); } @@ -242,7 +243,7 @@ waitForDeferredDeletes(); // There should be only invalid pointers in children - Q_FOREACH(QPointer<QObject> child, children) { + for (QPointer<QObject> child : std::as_const(children)) { //qDebug() << child; QVERIFY(child.isNull()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/tests/dbusmenushortcuttest.cpp new/libdbusmenu-lxqt-0.3.0/tests/dbusmenushortcuttest.cpp --- old/libdbusmenu-lxqt-0.2.0/tests/dbusmenushortcuttest.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/tests/dbusmenushortcuttest.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -36,7 +36,7 @@ char *toString(const DBusMenuShortcut &dmShortcut) { QByteArray ba = "DBusMenuShortcut("; - Q_FOREACH(const QStringList& tokens, dmShortcut) { + for(const QStringList& tokens : dmShortcut) { ba += "("; ba += tokens.join("+").toUtf8(); ba += ")"; @@ -49,8 +49,8 @@ DBusMenuShortcut createKeyList(const QString& txt) { DBusMenuShortcut lst; - QStringList tokens = txt.split(','); - Q_FOREACH(const QString& token, tokens) { + const QStringList tokens = txt.split(','); + for (const QString& token : tokens) { lst << token.split('+'); } return lst; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/tests/testutils.h new/libdbusmenu-lxqt-0.3.0/tests/testutils.h --- old/libdbusmenu-lxqt-0.2.0/tests/testutils.h 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/tests/testutils.h 2025-04-17 10:54:29.000000000 +0200 @@ -52,11 +52,11 @@ void receiveCall(DBusMenuItemList itemList, DBusMenuItemKeysList removedPropsList) { QVariantList propsIds; - Q_FOREACH(DBusMenuItem item, itemList) { + for (DBusMenuItem item : std::as_const(itemList)) { propsIds << item.id; } QVariantList removedPropsIds; - Q_FOREACH(DBusMenuItemKeys props, removedPropsList) { + for (DBusMenuItemKeys props : std::as_const(removedPropsList)) { removedPropsIds << props.id; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libdbusmenu-lxqt-0.2.0/tools/testapp/main.cpp new/libdbusmenu-lxqt-0.3.0/tools/testapp/main.cpp --- old/libdbusmenu-lxqt-0.2.0/tools/testapp/main.cpp 2024-11-05 06:18:35.000000000 +0100 +++ new/libdbusmenu-lxqt-0.3.0/tools/testapp/main.cpp 2025-04-17 10:54:29.000000000 +0200 @@ -50,8 +50,8 @@ QAction *action = menu->addAction(label); action->setEnabled(map.value("sensitive").toString() == "true"); if (map.contains("submenu")) { - QVariantList items = map.value("submenu").toList(); - Q_FOREACH(const QVariant &item, items) { + const QVariantList items = map.value("submenu").toList(); + for (const QVariant &item : items) { QMenu *subMenu = new QMenu; action->setMenu(subMenu); createMenuItem(subMenu, item); @@ -76,8 +76,8 @@ return; } - QVariantList list = tree.toList(); - Q_FOREACH(const QVariant &item, list) { + const QVariantList list = tree.toList(); + for (const QVariant &item : list) { createMenuItem(menu, item); } }