Skip to content

Commit

Permalink
feat(idle): replace xidlehook-core with user-idle
Browse files Browse the repository at this point in the history
this enables windows support and reduces complexity of the idle module
  • Loading branch information
maxjoehnk committed Dec 13, 2020
1 parent 9a6553a commit 261396a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 140 deletions.
54 changes: 11 additions & 43 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ log = "0.4"
env_logger = "0.8"
tokio = { version = "0.2", features = ["full"] }
mqtt-async-client = "0.1"
xidlehook-core = { git = "https://gitlab.com/jD91mZM2/xidlehook", features = ["tokio"], default-features = false }
user-idle = "0.2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.8"
Expand Down
112 changes: 16 additions & 96 deletions src/modules/idle.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use crate::config::Config;
use crate::modules::StateChange::Idle;
use crate::modules::{LocalModule, StateChange};
use futures_util::future::LocalBoxFuture;
use crate::modules::{StateChange, Module};
use futures_util::future::{BoxFuture};
use futures_util::FutureExt;
use std::time::Duration;
use tokio::sync::mpsc::UnboundedSender;
use xidlehook_core::modules::Xcb;
use xidlehook_core::Timer;
use xidlehook_core::Xidlehook;
use user_idle::UserIdle;

pub struct IdleModule {
sender: UnboundedSender<StateChange>,
Expand All @@ -19,102 +16,25 @@ impl IdleModule {
}
}

impl LocalModule for IdleModule {
fn run(&mut self, config: &Config) -> LocalBoxFuture<anyhow::Result<()>> {
impl Module for IdleModule {
fn run(&mut self, config: &Config) -> BoxFuture<anyhow::Result<()>> {
let idle_timeout = config.idle_timeout;
let poll_rate = config.idle_poll_rate;
async move {
self.sender.send(StateChange::Idle(false))?;
let timer = OccupancyTimer {
sender: self.sender.clone(),
time: Duration::from_secs(idle_timeout),
urgency: Duration::from_secs(poll_rate)
};
let mut idle_hook = Xidlehook::new(vec![timer]);
let xcb = Xcb::new().unwrap();
idle_hook.main_async(&xcb).await.unwrap();

Ok(())
}
.boxed_local()
}
}

pub struct OccupancyTimer {
pub time: Duration,
pub sender: UnboundedSender<StateChange>,
pub urgency: Duration,
}

impl Timer for OccupancyTimer {
fn time_left(&mut self, idle_time: Duration) -> xidlehook_core::Result<Option<Duration>> {
Ok(self
.time
.checked_sub(idle_time)
.filter(|&d| d != Duration::default()))
}

fn abort_urgency(&self) -> Option<Duration> {
Some(self.urgency)
}
loop {
tokio::time::delay_for(Duration::from_secs(poll_rate)).await;
let idle = UserIdle::get_time().map_err(|err| anyhow::Error::msg(err.to_string()))?;
if idle.as_seconds() >= idle_timeout {
self.sender.send(StateChange::Idle(true))?;
}else {
self.sender.send(StateChange::Idle(false))?;
}
}

fn activate(&mut self) -> xidlehook_core::Result<()> {
self.sender.send(Idle(true))?;
Ok(())
}

fn abort(&mut self) -> xidlehook_core::Result<()> {
self.sender.send(Idle(false))?;
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::state::StateChange;
use tokio::sync::mpsc;

#[test]
fn abort_urgency_should_return_urgency() {
for secs in vec![2, 5] {
let timer = OccupancyTimer {
time: Default::default(),
sender: mpsc::unbounded_channel().0,
urgency: Duration::from_secs(secs)
};

let urgency = timer.abort_urgency();

assert_eq!(Some(Duration::from_secs(secs)), urgency);
Ok(())
}
}

#[test]
fn activate_should_send_idle_true() {
let (sender, mut receiver) = mpsc::unbounded_channel();
let mut timer = OccupancyTimer {
time: Default::default(),
urgency: Default::default(),
sender,
};

timer.activate().unwrap();

assert_eq!(StateChange::Idle(true), receiver.try_recv().unwrap());
}

#[test]
fn abort_should_send_idle_false() {
let (sender, mut receiver) = mpsc::unbounded_channel();
let mut timer = OccupancyTimer {
time: Default::default(),
urgency: Default::default(),
sender,
};

timer.abort().unwrap();

assert_eq!(StateChange::Idle(false), receiver.try_recv().unwrap());
.boxed()
}
}

0 comments on commit 261396a

Please sign in to comment.