Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3:Rings:2-TestDVD
plasma5-workspace
0010-Reuse-QAction-and-QMenu-items-on-updates.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0010-Reuse-QAction-and-QMenu-items-on-updates.patch of Package plasma5-workspace
From 7fc50d60dbef6a18fffc2e2e7e1e3de5a01eb84a Mon Sep 17 00:00:00 2001 From: David Edmundson <kde@davidedmundson.co.uk> Date: Wed, 11 Jan 2017 13:52:57 +0000 Subject: [PATCH 10/44] Reuse QAction and QMenu items on updates Summary: When updating a menu we would always delete all the actions and recreate them. This caused a problem that we would also be deleting submenus and recreating them, meaning when we update the applet's submenu before showing it, our submenu will always be destroyed. This patch uses the DBusMenuItem IDs to re-use existing QAction / QMenu objects and only create new instances when needed. It should also be (in theory) faster as there's a lot less object creation every update. Also replace QSignalMapper with a lambda and replace replace QMap<int, QPointer<QAction*> with QMap<int, QAction*> and a lambda to do cleanup on deletion. Test Plan: Tweked the applet to update before showing Original QMenu object used before showing still has all the items Reviewers: #plasma Subscribers: broulik, markg, plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D4057 --- libdbusmenuqt/dbusmenuimporter.cpp | 49 ++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/libdbusmenuqt/dbusmenuimporter.cpp b/libdbusmenuqt/dbusmenuimporter.cpp index 9494c95f..2af1162f 100644 --- a/libdbusmenuqt/dbusmenuimporter.cpp +++ b/libdbusmenuqt/dbusmenuimporter.cpp @@ -29,7 +29,6 @@ #include <QFont> #include <QMenu> #include <QPointer> -#include <QSignalMapper> #include <QTime> #include <QTimer> #include <QToolButton> @@ -82,9 +81,8 @@ public: QDBusAbstractInterface *m_interface; QMenu *m_menu; - typedef QMap<int, QPointer<QAction> > ActionForId; + using ActionForId = QMap<int, QAction* >; ActionForId m_actionForId; - QSignalMapper m_mapper; QTimer *m_pendingLayoutUpdateTimer; QSet<int> m_idsRefreshedByAboutToShow; @@ -291,8 +289,6 @@ DBusMenuImporter::DBusMenuImporter(const QString &service, const QString &path, d->m_menu = 0; d->m_nPendingRequests = 0; - connect(&d->m_mapper, SIGNAL(mapped(int)), SLOT(sendClickedEvent(int))); - d->m_pendingLayoutUpdateTimer = new QTimer(this); d->m_pendingLayoutUpdateTimer->setSingleShot(true); connect(d->m_pendingLayoutUpdateTimer, &QTimer::timeout, this, &DBusMenuImporter::processPendingLayoutUpdates); @@ -411,22 +407,41 @@ void DBusMenuImporter::slotGetLayoutFinished(QDBusPendingCallWatcher *watcher) return; } - menu->clear(); + //remove outdated actions + QSet<int> newDBusMenuItemIds; + newDBusMenuItemIds.reserve(rootItem.children.count()); + for (const DBusMenuLayoutItem &item: rootItem.children) { + newDBusMenuItemIds << item.id; + } + for (QAction *action: menu->actions()) { + int id = action->property(DBUSMENU_PROPERTY_ID).toInt(); + if (! newDBusMenuItemIds.contains(id)) { + action->deleteLater(); + d->m_actionForId.remove(id); + } + } - Q_FOREACH(const DBusMenuLayoutItem &dbusMenuItem, rootItem.children) { - QAction *action = d->createAction(dbusMenuItem.id, dbusMenuItem.properties, menu); + //insert or update new actions into our menu + for (const DBusMenuLayoutItem &dbusMenuItem: rootItem.children) { DBusMenuImporterPrivate::ActionForId::Iterator it = d->m_actionForId.find(dbusMenuItem.id); + QAction *action = nullptr; if (it == d->m_actionForId.end()) { - d->m_actionForId.insert(dbusMenuItem.id, action); + int id = dbusMenuItem.id; + action = d->createAction(id, dbusMenuItem.properties, menu); + d->m_actionForId.insert(id, action); + connect(action, &QObject::destroyed, this, [this, id]() { + d->m_actionForId.remove(id); + }); + + connect(action, &QAction::triggered, this, [action, id, this]() { + sendClickedEvent(id); + }); + + menu->addAction(action); } else { - delete *it; - *it = action; + action = *it; + d->updateAction(*it, dbusMenuItem.properties, dbusMenuItem.properties.keys()); } - menu->addAction(action); - - connect(action, SIGNAL(triggered()), - &d->m_mapper, SLOT(map())); - d->m_mapper.setMapping(action, dbusMenuItem.id); if( action->menu() ) { @@ -515,8 +530,6 @@ void DBusMenuImporter::slotMenuAboutToShow() d->sendEvent(id, QStringLiteral("opened")); } - - QMenu *DBusMenuImporter::createMenu(QWidget *parent) { return new QMenu(parent); -- 2.12.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor