Files
ringa/src/main.rs
T
swaits 81d6237e2f feat: initial project with CPU-rendered ring light overlay
Wayland layer-shell overlay using tiny-skia for rendering a glowing
rounded rectangle ring. Includes PID-based lock file toggle via SIGUSR1,
keyboard capture (Escape to exit), and pointer tracking for cursor
avoidance. Configurable ring geometry and glow parameters.
2026-04-07 12:28:32 -06:00

75 lines
1.9 KiB
Rust

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)
}