tray_indicator/platform/
mod.rs1mod error;
2mod icon;
3mod notify_icon;
4mod popup_menu;
5mod string;
6mod util;
7
8pub(crate) use string::NativeString;
9
10use self::error::WinError;
11use crate::Tray;
12use std::cell::RefCell;
13
14thread_local! {
15 static TRAY_DATA: RefCell<Tray> = panic!("Tray data is not initialized");
16}
17
18pub(crate) fn display(tray: Tray) -> Result<(), TrayError> {
19 TRAY_DATA.set(tray);
20
21 unsafe {
22 let instance = notify_icon::get_instance()?;
23 let hwnd = notify_icon::create_window(instance)?;
24 notify_icon::create_notify_icon(instance, hwnd)?;
25 notify_icon::run_message_loop(hwnd);
26 }
27
28 Ok(())
29}
30
31pub(crate) fn exit() {
32 unsafe {
33 windows_sys::Win32::UI::WindowsAndMessaging::PostQuitMessage(0);
34 }
35}
36
37#[derive(Debug)]
38pub enum TrayError {
39 NoInstance(WinError),
40 WndClassRegister(WinError),
41 WindowCreate(WinError),
42 IconLoad(WinError),
43 Display,
44 Version,
45}
46
47impl std::fmt::Display for TrayError {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 TrayError::NoInstance(e) => write!(f, "Failed to get process instance handle. ({e})"),
51 TrayError::WndClassRegister(e) => write!(f, "Failed to register window class. ({e})"),
52 TrayError::WindowCreate(e) => write!(f, "Failed to create tray window. ({e})"),
53 TrayError::IconLoad(e) => write!(f, "Failed to load icon for tray. ({e})"),
54 TrayError::Display => write!(f, "Failed to display notify icon."),
55 TrayError::Version => write!(f, "Notify icon API version is not supported by the OS."),
56 }
57 }
58}
59
60impl std::error::Error for TrayError {
61 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
62 match self {
63 TrayError::NoInstance(e) => Some(e),
64 TrayError::WndClassRegister(e) => Some(e),
65 TrayError::WindowCreate(e) => Some(e),
66 TrayError::IconLoad(e) => Some(e),
67 TrayError::Display => None,
68 TrayError::Version => None,
69 }
70 }
71}