diff --git a/appmenu/appmenu.h b/appmenu/appmenu.h --- a/appmenu/appmenu.h +++ b/appmenu/appmenu.h @@ -28,6 +28,8 @@ #define APPMENUMODULE_H #include + +#include #include "menuimporter.h" class QDBusPendingCallWatcher; @@ -89,10 +91,9 @@ MenuImporter *m_menuImporter = nullptr; AppmenuDBus *m_appmenuDBus; + QPointer m_menu; - VerticalMenu *m_menu = nullptr; QAction *m_waitingAction = nullptr; - }; #endif diff --git a/appmenu/appmenu.cpp b/appmenu/appmenu.cpp --- a/appmenu/appmenu.cpp +++ b/appmenu/appmenu.cpp @@ -119,8 +119,8 @@ } // If menu visible, hide it - if (m_menu && m_menu->isVisible()) { - m_menu->hide(); + if (m_menu && m_menu.data()->isVisible()) { + m_menu.data()->hide(); return; } @@ -132,60 +132,41 @@ } auto *importer = new KDBusMenuImporter(serviceName, menuObjectPath.path(), this); - // FIXME this causes a 4 second freeze in dbusmenu when the app times out in aboutToShow - // DBusMenuImporter::slotMenuAboutToShow(): Application did not answer to AboutToShow() before timeout - //QMetaObject::invokeMethod(importer, "updateMenu", Qt::DirectConnection); QMetaObject::invokeMethod(importer, "updateMenu", Qt::QueuedConnection); - - /*connect(importer, &DBusMenuImporter::actionActivationRequested, this, [=](QAction *action) { - // else send request to kwin or others dbus interface registrars - m_waitingAction = action; - emit showRequest(serviceName, menuObjectPath); - });*/ + disconnect(importer, 0, this, 0); // ensure we don't popup multiple times in case the menu updates again later connect(importer, &KDBusMenuImporter::menuUpdated, this, [=] { QMenu *menu = importer->menu(); if (!menu) { return; } + m_menu = qobject_cast(menu); - const auto &actions = menu->actions(); - if (actions.isEmpty()) { - return; - } - - m_menu = new VerticalMenu(); - m_menu->setServiceName(serviceName); - m_menu->setMenuObjectPath(menuObjectPath); - - for (QAction *action : actions) { - m_menu->addAction(action); - } + m_menu.data()->setServiceName(serviceName); + m_menu.data()->setMenuObjectPath(menuObjectPath); - connect(m_menu, &QMenu::aboutToHide, this, [this, importer] { + connect(m_menu.data(), &QMenu::aboutToHide, this, [this, importer] { hideMenu(); importer->deleteLater(); }); //m_menuImporter->fakeUnityAboutToShow(serviceName, menuObjectPath); - m_menu->popup(QPoint(x, y)); + m_menu.data()->popup(QPoint(x, y)); emit menuShown(serviceName, menuObjectPath); if (m_waitingAction) { - m_menu->setActiveAction(m_waitingAction); + m_menu.data()->setActiveAction(m_waitingAction); m_waitingAction = nullptr; } }); } void AppMenuModule::hideMenu() { if (m_menu) { - emit menuHidden(m_menu->serviceName(), m_menu->menuObjectPath()); - m_menu->deleteLater(); - m_menu = nullptr; + emit menuHidden(m_menu.data()->serviceName(), m_menu->menuObjectPath()); } } diff --git a/appmenu/kdbusimporter.h b/appmenu/kdbusimporter.h --- a/appmenu/kdbusimporter.h +++ b/appmenu/kdbusimporter.h @@ -29,6 +29,7 @@ #include #include +#include "verticalmenu.h" class KDBusMenuImporter : public DBusMenuImporter { @@ -45,6 +46,9 @@ return QIcon::fromTheme(name); } + QMenu *createMenu(QWidget *parent) override { + return new VerticalMenu(parent); + } }; #endif //KDBUSMENUIMPORTER_H