From edce19bb803211d8ee521e5e2c27a69e013d98c7 Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Sun, 10 May 2026 12:50:29 +0200 Subject: [PATCH] Revert "fix(tray): open dbusmenu before layout fetch and show id-only rows" This reverts commit e5231e91ff5b3564900f4d4dead61f57e7821eda. --- src/dbus/tray/tray_service.cpp | 20 ++++---------------- src/dbus/tray/tray_service.h | 2 -- src/shell/tray/tray_menu.cpp | 16 +++++++++++----- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/dbus/tray/tray_service.cpp b/src/dbus/tray/tray_service.cpp index bef27c8ea..024e48251 100644 --- a/src/dbus/tray/tray_service.cpp +++ b/src/dbus/tray/tray_service.cpp @@ -275,8 +275,10 @@ namespace { if (entry.id <= 0 || !entry.visible) { 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. + if (entry.label.empty() && !entry.separator && !entry.hasSubmenu && entry.iconName.empty() && + entry.iconData.empty()) { + return false; + } return true; } @@ -899,20 +901,6 @@ 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) { diff --git a/src/dbus/tray/tray_service.h b/src/dbus/tray/tray_service.h index 37d0c430a..90e461999 100644 --- a/src/dbus/tray/tray_service.h +++ b/src/dbus/tray/tray_service.h @@ -79,8 +79,6 @@ 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 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); diff --git a/src/shell/tray/tray_menu.cpp b/src/shell/tray/tray_menu.cpp index 5fd41e20b..c5f55b520 100644 --- a/src/shell/tray/tray_menu.cpp +++ b/src/shell/tray/tray_menu.cpp @@ -323,10 +323,6 @@ 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; @@ -336,6 +332,14 @@ 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(); } @@ -973,7 +977,6 @@ 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; @@ -983,6 +986,9 @@ 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(m_instance->surface->width());