File 0011-Replace-recursive-layout-loading-with-dynamic-loadin.patch of Package plasma5-workspace

From 9924733a072cc657cb0554234078a3dec827a3eb Mon Sep 17 00:00:00 2001
From: David Edmundson <kde@davidedmundson.co.uk>
Date: Wed, 11 Jan 2017 13:55:14 +0000
Subject: [PATCH 11/44] Replace recursive layout loading with dynamic loading

Summary:
The previous code worked as follows:
- when we show a menu we would emit aboutToShow on the root item
- we would then recursively load the /entire/ menu structure before
emitting we were done.

Because we only sent aboutToShow on the root menu, any clients that were connected to
a submenu's aboutToShow never got an aboutToShow signal.

This patch does the (in retrospect far more obvious) fix of just
calling aboutToShow dynamically on each submenu when it's time to show,
then updating the menu whilst it's showing.

Test Plan: Dynamic menus now work, DBus traffic is considerably down

Reviewers: #plasma, broulik

Reviewed By: #plasma, broulik

Subscribers: broulik, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D4059
---
 libdbusmenuqt/dbusmenuimporter.cpp | 45 ++++++++++++++------------------------
 libdbusmenuqt/dbusmenuimporter.h   |  2 ++
 2 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/libdbusmenuqt/dbusmenuimporter.cpp b/libdbusmenuqt/dbusmenuimporter.cpp
index 2af1162f..dd77b2e3 100644
--- a/libdbusmenuqt/dbusmenuimporter.cpp
+++ b/libdbusmenuqt/dbusmenuimporter.cpp
@@ -87,15 +87,9 @@ public:
 
     QSet<int> m_idsRefreshedByAboutToShow;
     QSet<int> m_pendingLayoutUpdates;
-    int m_nPendingRequests;
 
     QDBusPendingCallWatcher *refresh(int id)
     {
-        m_nPendingRequests++;
-        #ifdef BENCHMARK
-        DMDEBUG << "Starting refresh chrono for id" << id;
-        sChrono.start();
-        #endif
         QDBusPendingCall call = m_interface->asyncCall(QStringLiteral("GetLayout"), id, 1, QStringList());
         QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(call, q);
         watcher->setProperty(DBUSMENU_PROPERTY_ID, id);
@@ -287,7 +281,6 @@ DBusMenuImporter::DBusMenuImporter(const QString &service, const QString &path,
     d->q = this;
     d->m_interface = new QDBusInterface(service, path, DBUSMENU_INTERFACE, QDBusConnection::sessionBus(), this);
     d->m_menu = 0;
-    d->m_nPendingRequests = 0;
 
     d->m_pendingLayoutUpdateTimer = new QTimer(this);
     d->m_pendingLayoutUpdateTimer->setSingleShot(true);
@@ -383,16 +376,11 @@ void DBusMenuImporter::slotGetLayoutFinished(QDBusPendingCallWatcher *watcher)
     int parentId = watcher->property(DBUSMENU_PROPERTY_ID).toInt();
     watcher->deleteLater();
 
-    d->m_nPendingRequests--;
-
     QDBusPendingReply<uint, DBusMenuLayoutItem> reply = *watcher;
     if (!reply.isValid()) {
         qWarning() << reply.error().message();
 
-        if (d->m_nPendingRequests == 0) {
-            emit menuUpdated();
-        }
-
+        emit menuUpdated();
         return;
     }
 
@@ -429,6 +417,7 @@ void DBusMenuImporter::slotGetLayoutFinished(QDBusPendingCallWatcher *watcher)
             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);
             });
@@ -437,25 +426,21 @@ void DBusMenuImporter::slotGetLayoutFinished(QDBusPendingCallWatcher *watcher)
                 sendClickedEvent(id);
             });
 
+            if (action->menu()) {
+                auto menu = action->menu();
+                connect(menu, &QMenu::aboutToShow, this, [menu, this]() {
+                   updateMenu(menu);
+                });
+            }
+
             menu->addAction(action);
         } else {
             action = *it;
             d->updateAction(*it, dbusMenuItem.properties, dbusMenuItem.properties.keys());
         }
-
-        if( action->menu() )
-        {
-          d->refresh( dbusMenuItem.id );
-        }
     }
 
-    if (d->m_nPendingRequests == 0) {
-        emit menuUpdated();
-    }
-
-    #ifdef BENCHMARK
-    DMDEBUG << "- Menu filled:" << sChrono.elapsed() << "ms";
-    #endif
+    emit menuUpdated();
 }
 
 void DBusMenuImporter::sendClickedEvent(int id)
@@ -465,7 +450,11 @@ void DBusMenuImporter::sendClickedEvent(int id)
 
 void DBusMenuImporter::updateMenu()
 {
-    QMenu *menu = DBusMenuImporter::menu();
+    updateMenu(DBusMenuImporter::menu());
+}
+
+void DBusMenuImporter::updateMenu(QMenu * menu)
+{
     Q_ASSERT(menu);
 
     QAction *action = menu->menuAction();
@@ -480,8 +469,6 @@ void DBusMenuImporter::updateMenu()
         &DBusMenuImporter::slotAboutToShowDBusCallFinished);
 }
 
-
-
 void DBusMenuImporter::slotAboutToShowDBusCallFinished(QDBusPendingCallWatcher *watcher)
 {
     int id = watcher->property(DBUSMENU_PROPERTY_ID).toInt();
@@ -493,6 +480,8 @@ void DBusMenuImporter::slotAboutToShowDBusCallFinished(QDBusPendingCallWatcher *
         qWarning() << "Call to AboutToShow() failed:" << reply.error().message();
         return;
     }
+    //Note, this isn't used by Qt's QPT - but we get a LayoutChanged emitted before
+    //this returns, which equates to the same thing
     bool needRefresh = reply.argumentAt<0>();
 
     QMenu *menu = d->menuForId(id);
diff --git a/libdbusmenuqt/dbusmenuimporter.h b/libdbusmenuqt/dbusmenuimporter.h
index 643e0d1e..9ab87c6e 100644
--- a/libdbusmenuqt/dbusmenuimporter.h
+++ b/libdbusmenuqt/dbusmenuimporter.h
@@ -62,6 +62,8 @@ public Q_SLOTS:
      */
     void updateMenu();
 
+    void updateMenu(QMenu *menu);
+
 Q_SIGNALS:
     /**
      * Emitted after a call to updateMenu().
-- 
2.12.0

openSUSE Build Service is sponsored by