diff --git a/libdbusmenuqt/dbusmenuimporter.cpp b/libdbusmenuqt/dbusmenuimporter.cpp --- a/libdbusmenuqt/dbusmenuimporter.cpp +++ b/libdbusmenuqt/dbusmenuimporter.cpp @@ -401,22 +401,12 @@ return; } - //remove outdated actions - QSet 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)) { - menu->removeAction(action); - action->deleteLater(); - d->m_actionForId.remove(id); - } - } - //insert or update new actions into our menu + // XXX: it's important to insert new actions before removing old ones + // Otherwise the following might happen for applications that generate menus on-the-fly (i.e. LyX) + // user opens a menu -> menu is generated (updated) -> we arrive here + // -> we remove all the items before populating with new -> menu gets instantly closed, because it's empty + // -> menu gets updated, but nobody notices it, as it's already closed :( for (const DBusMenuLayoutItem &dbusMenuItem: rootItem.children) { DBusMenuImporterPrivate::ActionForId::Iterator it = d->m_actionForId.find(dbusMenuItem.id); QAction *action = nullptr; @@ -451,6 +441,20 @@ menu->addAction(action); } } + //remove outdated actions + QSet 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)) { + menu->removeAction(action); + action->deleteLater(); + d->m_actionForId.remove(id); + } + } emit menuUpdated(menu); }