1use std::thread;
13use std::time::Duration;
14
15use ldtray::{Event, Icon, Menu, MenuItem, Notification, Tray, TrayConfig};
16
17fn demo_icon() -> Icon {
18 let side = 16u32;
19 let mut rgba = Vec::with_capacity((side * side * 4) as usize);
20 for _ in 0..side * side {
21 rgba.extend_from_slice(&[10, 120, 220, 255]);
22 }
23 Icon::from_rgba(side, side, rgba).expect("valid icon")
24}
25
26fn demo_menu() -> Menu {
27 Menu::new()
28 .item(MenuItem::button(1, "One"))
29 .item(MenuItem::checkbox(2, "Toggle", true))
30 .item(MenuItem::separator())
31 .item(MenuItem::submenu("More", [MenuItem::button(3, "Nested")]))
32 .item(MenuItem::button(9, "Quit"))
33}
34
35fn main() {
36 thread::spawn(|| {
38 thread::sleep(Duration::from_secs(20));
39 eprintln!("SMOKE_TIMEOUT: event loop did not finish");
40 std::process::exit(3);
41 });
42
43 let config = TrayConfig::new(demo_icon())
44 .tooltip("ldtray smoke")
45 .menu(demo_menu());
46
47 let tray = match Tray::new(config) {
48 Ok(tray) => tray,
49 Err(err) => {
50 if cfg!(any(target_os = "windows", target_os = "macos")) {
54 eprintln!("SMOKE_FAIL: Tray::new failed on a GUI OS: {err}");
55 std::process::exit(1);
56 }
57 eprintln!("SMOKE_SKIP: no tray in this environment: {err}");
58 return;
59 }
60 };
61
62 let handle = tray.handle();
64 let driver = thread::spawn(move || {
65 thread::sleep(Duration::from_millis(400));
66 let _ = handle.set_tooltip("updated tooltip");
67 let _ = handle.set_icon(demo_icon());
68 let _ = handle.set_menu(demo_menu());
69 let _ = handle.notify(Notification::new("ldtray", "smoke").with_icon(demo_icon()));
70 thread::sleep(Duration::from_millis(400));
71 let _ = handle.quit();
72 });
73
74 let mut events = 0usize;
75 let result = tray.run(|event: Event| {
76 events += 1;
77 println!("event: {event:?}");
78 });
79 let _ = driver.join();
80
81 match result {
82 Ok(()) => {
83 println!("SMOKE_OK: ran cleanly ({events} events)");
84 }
85 Err(err) => {
86 eprintln!("SMOKE_FAIL: event loop ended with error: {err}");
87 std::process::exit(2);
88 }
89 }
90}