Skip to content
67 linesCodeBlameRaw
1//! The badge: what needs the person, on the app's icon and in the tray's
2//! hover text. macOS and Linux draw a count on the icon; Windows has no
3//! count, so it gets a lavender dot over the taskbar icon instead. With
4//! the badge turned off in settings, the icon stays clean and only the
5//! tray's hover text counts.
6
7use tauri::{AppHandle, Manager};
8
9use crate::{WINDOW, config, tray};
10
11pub fn set(app: &AppHandle, count: i64) {
12 *app.state::<config::State>().waiting.lock().unwrap() = count;
13 let shown = if config::settings(app).badge { count } else { 0 };
14 if let Some(window) = app.get_webview_window(WINDOW) {
15 #[cfg(target_os = "windows")]
16 let _ = window.set_overlay_icon(if shown > 0 { Some(dot()) } else { None });
17 #[cfg(not(target_os = "windows"))]
18 let _ = window.set_badge_count(if shown > 0 { Some(shown) } else { None });
19 }
20 if let Some(tray) = app.tray_by_id(tray::TRAY) {
21 let text = match count {
22 0 => "g1t".to_string(),
23 1 => "g1t · 1 thing waiting for you".to_string(),
24 n => format!("g1t · {n} things waiting for you"),
25 };
26 let _ = tray.set_tooltip(Some(text));
27 }
28}
29
30/// Draws the badge again, after the setting changed.
31pub fn refresh(app: &AppHandle) {
32 let count = *app.state::<config::State>().waiting.lock().unwrap();
33 set(app, count);
34}
35
36/// A lavender dot with a dark edge, 32 pixels square, drawn here so
37/// nothing needs loading.
38#[cfg(target_os = "windows")]
39fn dot() -> tauri::image::Image<'static> {
40 const SIZE: usize = 32;
41 let mut rgba = vec![0u8; SIZE * SIZE * 4];
42 let centre = (SIZE as f32 - 1.0) / 2.0;
43 let radius = SIZE as f32 / 2.0;
44 for y in 0..SIZE {
45 for x in 0..SIZE {
46 let dx = x as f32 - centre;
47 let dy = y as f32 - centre;
48 let distance = (dx * dx + dy * dy).sqrt();
49 // Lavender inside, a thin dark ring, then nothing; the edges blend.
50 let (colour, alpha) = if distance <= radius - 3.0 {
51 ([0xb6, 0xa8, 0xff], 1.0)
52 } else if distance <= radius - 0.5 {
53 ([0x0f, 0x0f, 0x11], 1.0)
54 } else if distance <= radius + 0.5 {
55 ([0x0f, 0x0f, 0x11], radius + 0.5 - distance)
56 } else {
57 ([0, 0, 0], 0.0)
58 };
59 let at = (y * SIZE + x) * 4;
60 rgba[at] = colour[0];
61 rgba[at + 1] = colour[1];
62 rgba[at + 2] = colour[2];
63 rgba[at + 3] = (alpha.clamp(0.0, 1.0) * 255.0) as u8;
64 }
65 }
66 tauri::image::Image::new_owned(rgba, SIZE as u32, SIZE as u32)
67}