xbp_cli/utils/
tray_runtime.rs1use tray_icon::Icon;
4
5const TRAY_ICON_SIZE: u32 = 32;
6
7pub fn load_tray_icon_from_png(bytes: &[u8]) -> Result<Icon, String> {
9 let image = image::load_from_memory(bytes)
10 .map_err(|error| format!("Failed to decode tray icon: {error}"))?
11 .into_rgba8();
12
13 let image = if image.width() > TRAY_ICON_SIZE || image.height() > TRAY_ICON_SIZE {
14 image::imageops::resize(
15 &image,
16 TRAY_ICON_SIZE,
17 TRAY_ICON_SIZE,
18 image::imageops::FilterType::Lanczos3,
19 )
20 } else {
21 image
22 };
23
24 let (width, height) = (image.width(), image.height());
25 Icon::from_rgba(image.into_raw(), width, height)
26 .map_err(|error| format!("Failed to create tray icon: {error}"))
27}
28
29pub fn pump_tray_events() {
31 #[cfg(windows)]
32 pump_windows_events();
33
34 #[cfg(target_os = "linux")]
35 pump_gtk_events();
36}
37
38#[cfg(windows)]
39fn pump_windows_events() {
40 use std::mem::zeroed;
41 use windows_sys::Win32::UI::WindowsAndMessaging::{
42 DispatchMessageW, PeekMessageW, TranslateMessage, MSG, PM_REMOVE,
43 };
44
45 unsafe {
46 let mut msg: MSG = zeroed();
47 while PeekMessageW(&mut msg, std::ptr::null_mut(), 0, 0, PM_REMOVE) != 0 {
48 TranslateMessage(&msg);
49 DispatchMessageW(&msg);
50 }
51 }
52}
53
54#[cfg(target_os = "linux")]
55fn pump_gtk_events() {
56 while gtk::events_pending() {
57 gtk::main_iteration();
58 }
59}