fix(status-area): lazy-load status notifier menu layouts to prevent DBus timeouts

Previously, the applet subscribed to layout updates for all items immediately
upon registration (eager-loading). This caused severe issues with applications
like VLC, which fail to respond to `com.canonical.dbusmenu.GetLayout` calls
during high-load operations (e.g., initializing video playback).

These unanswered calls resulted in DBus timeouts that:
1. Flooded the connection queue.
2. Blocked the processing of other signals (like `Unregistered`).
3. Caused the applet to become unresponsive and the icon to persist (ghosting).

This patch modifies the subscription logic to only subscribe to layout updates
when the specific menu is actually open. This "lazy-loading" approach:
- Prevents hitting applications with DBus calls during vulnerable states.
- Drastically reduces unnecessary DBus traffic.
This commit is contained in:
mikairyuu 2026-01-10 17:08:57 +09:00 committed by Michael Murphy
parent 6e74e90ea2
commit c8104a98ce
2 changed files with 10 additions and 6 deletions

View file

@ -453,7 +453,8 @@ impl cosmic::Application for App {
subscriptions.push(status_notifier_watcher::subscription().map(Msg::StatusNotifier));
for (id, menu) in &self.menus {
subscriptions.push(menu.subscription().with(*id).map(Msg::StatusMenu));
let is_open = self.open_menu == Some(*id);
subscriptions.push(menu.subscription(is_open).with(*id).map(Msg::StatusMenu));
}
subscriptions.push(activation_token_subscription(0).map(Msg::Token));

View file

@ -157,11 +157,14 @@ impl State {
}
}
pub fn subscription(&self) -> iced::Subscription<Msg> {
iced::Subscription::batch([
self.item.layout_subscription().map(Msg::Layout),
self.item.icon_subscription().map(Msg::Icon),
])
pub fn subscription(&self, is_open: bool) -> iced::Subscription<Msg> {
let mut subscriptions = vec![self.item.icon_subscription().map(Msg::Icon)];
if is_open {
subscriptions.push(self.item.layout_subscription().map(Msg::Layout));
}
iced::Subscription::batch(subscriptions)
}
pub fn opened(&self) {