mod lock; mod render; mod wayland; use std::time::{Duration, Instant}; use anyhow::{Context, Result}; use tiny_skia::Pixmap; use lock::ToggleResult; use wayland::{OverlayEvent, WaylandBackend}; const DISPLAY_DURATION: Duration = Duration::from_secs(5); fn main() -> Result<()> { match lock::try_toggle()? { ToggleResult::SignaledExisting => return Ok(()), ToggleResult::RunNew => {} } let _lock = lock::create_lock()?; let mut wl = WaylandBackend::new()?; let (w, h) = wl.screen_size(); let mut pixmap = Pixmap::new(w, h).context("create pixmap")?; let mut argb_buf = vec![0u8; (w as usize) * (h as usize) * 4]; let mut cursor_x = w as f64 / 2.0; let mut cursor_y = h as f64 / 2.0; draw(&mut wl, &mut pixmap, &mut argb_buf, cursor_x, cursor_y)?; let start = Instant::now(); loop { let elapsed = start.elapsed(); if elapsed >= DISPLAY_DURATION || lock::should_exit() { break; } let remaining = DISPLAY_DURATION - elapsed; let event = match wl.next_event(remaining)? { Some(ev) => ev, None => continue, // poll timeout — loop back to check elapsed time }; match event { OverlayEvent::Close => break, OverlayEvent::CursorMoved(x, y) => { cursor_x = x; cursor_y = y; draw(&mut wl, &mut pixmap, &mut argb_buf, cursor_x, cursor_y)?; } OverlayEvent::Configure(new_w, new_h) => { if new_w != w || new_h != h { break; } } } } Ok(()) } fn draw( wl: &mut WaylandBackend, pixmap: &mut Pixmap, argb_buf: &mut [u8], cursor_x: f64, cursor_y: f64, ) -> Result<()> { render::render_ring_light(pixmap, cursor_x, cursor_y); render::pixmap_to_argb8888(pixmap, argb_buf); let (w, h) = wl.screen_size(); wl.present(argb_buf, w, h) }