/* Polydoro - Pomodoro widget for polybar and friends * Copyright (C) 2025 Vidhu Kant Sharma * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ use std::sync::mpsc::Receiver; use std::thread; use std::time::Duration; use std::os::unix::net::{UnixStream,UnixListener}; use bincode::{encode_into_std_write,config}; use crate::daemon::pomo::Pomo; use crate::daemon::command::Command; pub fn start_clock(rx: Receiver) -> thread::JoinHandle<()> { thread::spawn(move || { let mut p = Pomo::new(); // check if a socket already exists (only one daemon allowed!) let sock = "/tmp/polydorod.sock"; if std::fs::metadata(sock).is_ok() { eprintln!("socket {} already exists, is another daemon running?", sock); std::process::exit(1); } // all OK, create a sock let listener = UnixListener::bind(sock).expect("failed to bind socket /tmp/polydorod.sock"); listener.set_nonblocking(true).unwrap(); // all of the connected listeners let mut listeners: Vec = Vec::new(); loop { // if new listener is connected match listener.accept() { Ok((stream, _addr)) => { listeners.push(stream); } Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {} // no new client Err(e) => eprintln!("error while adding new listener: {}", e), } // listen to commands while let Ok(cmd) = rx.try_recv() { match cmd { Command::Run => p.run(), Command::Pause => p.pause(), Command::Toggle => p.toggle(), Command::Skip => p.end_cycle(), Command::SoftReset => p.soft_reset(), Command::HardReset => p.hard_reset(), Command::Reset => p.reset(), } } p.tick(); // send p struct to the listeners listening to polydorod.sock listeners.retain_mut(|l| { if let Err(_) = encode_into_std_write(&p, l, config::standard()) { false // drop this listener, seems to be disconnected } else { true } }); thread::sleep(Duration::from_secs(1)); } }) }