fix(tray): open dbusmenu before layout fetch and show id-only rows

This commit is contained in:
Ly-sec
2026-05-10 12:33:11 +02:00
parent e43535c17f
commit e5231e91ff
3 changed files with 23 additions and 15 deletions
+16 -4
View File
@@ -275,10 +275,8 @@ namespace {
if (entry.id <= 0 || !entry.visible) {
return false;
}
if (entry.label.empty() && !entry.separator && !entry.hasSubmenu && entry.iconName.empty() &&
entry.iconData.empty()) {
return false;
}
// Keep rows whose labels (and icons) arrive only after ItemsPropertiesUpdated — the old Quickshell path
// would still materialize these ids while the layout was filling in.
return true;
}
@@ -901,6 +899,20 @@ void TrayService::notifyMenuClosed(const std::string& itemId, std::int32_t entry
sendMenuEvent(itemId, entryId, "closed");
}
void TrayService::primeMenuForOpen(const std::string& itemId) {
if (!ensureItemProxy(itemId)) {
return;
}
const auto itemIt = m_items.find(itemId);
if (itemIt == m_items.end()) {
return;
}
if (itemIt->second.busName.empty() || itemIt->second.menuObjectPath.empty()) {
return;
}
ensureMenuCache(itemId, itemIt->second.busName, itemIt->second.menuObjectPath);
}
bool TrayService::activateMenuEntry(const std::string& itemId, std::int32_t entryId) {
auto it = m_menuCache.find(itemId);
if (it == m_menuCache.end() || it->second.proxy == nullptr) {
+2
View File
@@ -79,6 +79,8 @@ public:
// open/close cycles.
void notifyMenuOpened(const std::string& itemId, std::int32_t entryId = 0);
void notifyMenuClosed(const std::string& itemId, std::int32_t entryId = 0);
/// Ensures the dbusmenu proxy exists so notifyMenuOpened runs before the first menuEntries fetch.
void primeMenuForOpen(const std::string& itemId);
[[nodiscard]] std::vector<std::string> registeredItems() const;
[[nodiscard]] bool activateItem(const std::string& itemId, std::int32_t x = 0, std::int32_t y = 0);
[[nodiscard]] bool openContextMenu(const std::string& itemId, std::int32_t x = 0, std::int32_t y = 0);
+5 -11
View File
@@ -323,6 +323,10 @@ void TrayMenu::toggleForItem(const std::string& itemId) {
}
m_activeItemId = itemId;
if (m_tray != nullptr) {
m_tray->primeMenuForOpen(itemId);
m_tray->notifyMenuOpened(m_activeItemId);
}
refreshEntries();
m_visible = true;
@@ -332,14 +336,6 @@ void TrayMenu::toggleForItem(const std::string& itemId) {
return;
}
// Notify the dbusmenu server the root menu is being opened. Well-behaved
// servers (including Electron) rely on paired opened/closed events to reset
// internal state — skipping them causes their handlers to desync after many
// open/close cycles, eventually returning errors on every GetLayout.
if (m_tray != nullptr) {
m_tray->notifyMenuOpened(m_activeItemId);
}
rebuildScenes();
}
@@ -977,6 +973,7 @@ void TrayMenu::openSubmenu(std::int32_t parentEntryId, float rowCenterY) {
return;
}
m_tray->notifyMenuOpened(m_activeItemId, parentEntryId);
m_submenuEntries = m_tray->menuEntriesForParent(m_activeItemId, parentEntryId);
if (m_submenuEntries.empty()) {
m_pendingSubmenuParentEntryId = parentEntryId;
@@ -986,9 +983,6 @@ void TrayMenu::openSubmenu(std::int32_t parentEntryId, float rowCenterY) {
m_pendingSubmenuParentEntryId = 0;
m_pendingSubmenuRowCenterY = 0.0f;
m_submenuParentEntryId = parentEntryId;
// Signal the server that this submenu is being opened. Matches the opened/closed
// pairing we do for the root menu.
m_tray->notifyMenuOpened(m_activeItemId, parentEntryId);
// Anchor rect is in the main popup's coordinate space (0,0 = top-left of main popup surface)
const auto mainWidth = static_cast<std::int32_t>(m_instance->surface->width());