diff options
Diffstat (limited to 'src/daemon/clock.rs')
-rw-r--r-- | src/daemon/clock.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/daemon/clock.rs b/src/daemon/clock.rs new file mode 100644 index 0000000..98ad292 --- /dev/null +++ b/src/daemon/clock.rs @@ -0,0 +1,82 @@ +/* Polydoro - Pomodoro widget for polybar and friends + * Copyright (C) 2025 Vidhu Kant Sharma <vidhukant@vidhukant.com> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +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<Command>) -> 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<UnixStream> = 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)); + } + }) +} |