Skip to content

Commit

Permalink
fix: filter out hidden icons in systray (#196)
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger authored Feb 27, 2025
1 parent 12355e5 commit 10302cf
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
9 changes: 9 additions & 0 deletions crates/systray-util/src/systray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ pub struct SystrayIcon {

/// Version of the icon.
pub version: Option<u32>,

/// Whether the icon is visible in the system tray.
///
/// This is determined by the `NIS_HIDDEN` flag in the icon's state.
pub is_visible: bool,
}

// Debug implementation for `SystrayIcon`. Icon image is a large
Expand All @@ -128,6 +133,7 @@ impl std::fmt::Debug for SystrayIcon {
.field("icon_image", &self.icon_image.as_ref().map(|_| "..."))
.field("callback_message", &self.callback_message)
.field("version", &self.version)
.field("is_visible", &self.is_visible)
.finish()
}
}
Expand Down Expand Up @@ -292,6 +298,8 @@ impl Systray {
found_icon.version = Some(version);
}

found_icon.is_visible = icon_data.is_visible;

Some(SystrayEvent::IconUpdate(found_icon.clone()))
} else {
// Icon doesn't exist yet, so add new icon. Skip icons that
Expand Down Expand Up @@ -322,6 +330,7 @@ impl Systray {
icon_image,
callback_message: icon_data.callback_message,
version: icon_data.version,
is_visible: icon_data.is_visible,
};

self.icons.insert(icon.stable_id.clone(), icon.clone());
Expand Down
18 changes: 15 additions & 3 deletions crates/systray-util/src/tray_spy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use windows::{
Threading::{OpenProcess, PROCESS_ALL_ACCESS},
},
UI::{
Controls::TBBUTTON,
Controls::{TBBUTTON, TBSTATE_HIDDEN},
Shell::{
NIF_GUID, NIF_ICON, NIF_MESSAGE, NIF_TIP, NIM_ADD, NIM_DELETE,
NIM_MODIFY, NIM_SETVERSION, NOTIFYICONDATAW_0,
NIM_MODIFY, NIM_SETVERSION, NIS_HIDDEN, NOTIFYICONDATAW_0,
NOTIFY_ICON_DATA_FLAGS, NOTIFY_ICON_INFOTIP_FLAGS,
NOTIFY_ICON_MESSAGE, NOTIFY_ICON_STATE,
},
Expand Down Expand Up @@ -131,6 +131,7 @@ pub(crate) struct IconEventData {
pub icon_handle: Option<isize>,
pub callback_message: Option<u32>,
pub version: Option<u32>,
pub is_visible: bool,
}

impl From<NotifyIconData> for IconEventData {
Expand Down Expand Up @@ -185,6 +186,8 @@ impl From<NotifyIconData> for IconEventData {
None
};

let is_visible = icon_data.state.0 & NIS_HIDDEN.0 == 0;

IconEventData {
uid,
window_handle,
Expand All @@ -193,6 +196,7 @@ impl From<NotifyIconData> for IconEventData {
icon_handle,
callback_message,
version,
is_visible,
}
}
}
Expand Down Expand Up @@ -227,6 +231,9 @@ impl From<TbButtonItem> for IconEventData {
icon_handle,
callback_message: Some(tb_item.callback_message),
version: Some(tb_item.version),
// Determined by the parent `TBBUTTON` struct. This value is set
// after initialization.
is_visible: true,
}
}
}
Expand Down Expand Up @@ -541,7 +548,12 @@ impl TraySpy {
)
}?;

Ok(tray_item.into())
let mut icon_event: IconEventData = tray_item.into();

// Hidden state is determined by the toolbar button state.
icon_event.is_visible = button.fsState & TBSTATE_HIDDEN as u8 == 0;

Ok(icon_event)
}

/// Whether a message should be forwarded to the real tray window.
Expand Down
1 change: 1 addition & 0 deletions packages/desktop/src/providers/systray/systray_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ impl Provider for SystrayProvider {
icons: systray
.icons()
.into_iter()
.filter(|icon| icon.is_visible)
.filter_map(|icon| SystrayOutputIcon::try_from(icon).ok())
.collect(),
}));
Expand Down

0 comments on commit 10302cf

Please sign in to comment.