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.
This commit is contained in:
7 files changed
+1484
No files matched your search
+74
@@ -0,0 +1,74 @@
|
||||
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)
|
||||
}
|
||||
Reference in new issue
Block a user