-
Couldn't load subscription status.
- Fork 55
Description
The Problem
I have created some local Linux utilities that have tray icons and I encountered a limitation where if you run more than one app (that uses tray-icon) simultaneously e.g. when they are auto-started by systemd, you'll find that there are cases where tray-icon objects are created without icons (see below).
This is how the icons are on disk:
My Theory
The missing icon was overwritten by one of the apps that were started later as there's currently no safe-guards to prevent 2 apps (using tray-icon) from generating the same path e.g. app_1 generates the path to it's first icon as /run/user/1000/tray-icon/tray-icon-1-1.png, but there's nothing stopping app_2 from generating the same path, /run/user/1000/tray-icon/tray-icon-1-1.png. Therefore, app_2 will overwrite the icon for app_1.
Possible Solution
Solution 1
We can allow the user to specify a unique string that can help to distinguish between the icons.
And the functionality to do this is already present in the code. If you look at the function below, an id is passed in that forms part of the final path to the icon.
tray-icon/src/platform_impl/gtk/mod.rs
Line 135 in 97723fd
| let icon_path = parent_path.join(format!("tray-icon-{}-{}.png", id, counter)); |
The problem is that an auto-generated id is created by tray-icon, meaning that all apps end up generating the same id...
tray-icon/src/platform_impl/gtk/mod.rs
Lines 24 to 29 in 97723fd
| pub fn new(_id: TrayIconId, attrs: TrayIconAttributes) -> crate::Result<Self> { | |
| let id = COUNTER.next(); | |
| let mut indicator = AppIndicator::new("tray-icon tray app", ""); | |
| indicator.set_status(AppIndicatorStatus::Active); | |
| let (parent_path, icon_path) = temp_icon_path(attrs.temp_dir_path.as_ref(), id, 0)?; |
If you look at the snippet above, while an id is passed into the initializer i.e. _id, it's not used. Instead a private id is generated using the COUNTER. Because all apps go through the same logic path, the counter will always output a value of 2 for all apps using this package thus leading to naming conflicts and possible file collisions.
Solution 2
If the existing behavior is intended, a workaround solution is to create a loop that checks if the generated path is already in use. If it's already in use, you increment the counter then check again.
Conclusion
Before I label this behavior as a bug, I'd like to know if this behavior is intentional. Thanks.

