Skip to content

Commit

Permalink
Add --detect-sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
jD91mZM2 committed Jan 30, 2021
1 parent 705f969 commit 6647a5f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
57 changes: 55 additions & 2 deletions xidlehook-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@
//! This library lets you create your own xidlehook front-end using a
//! powerful timer and module system.
use std::{cmp, convert::TryInto, fmt, ptr, time::Duration};
use std::{
cmp,
convert::TryInto,
fmt, ptr,
time::{Duration, Instant},
};

use log::{trace, warn};
use log::{info, trace, warn};
use nix::libc;

/// The default error type for xidlehook. Unfortunately, it's a
Expand Down Expand Up @@ -77,6 +82,9 @@ where
{
module: M,

/// Whether to reset on sleep
detect_sleep: bool,

timers: Vec<T>,
next_index: usize,
/// The base idle time: the absolute idle time when the last timer
Expand All @@ -95,6 +103,8 @@ impl<T: Timer> Xidlehook<T, ()> {
Self {
module: (),

detect_sleep: false,

timers,
next_index: 0,
base_idle_time: Duration::default(),
Expand All @@ -108,6 +118,9 @@ macro_rules! with_module {
($self:expr, $module:expr) => {
Xidlehook {
module: $module,

detect_sleep: $self.detect_sleep,

timers: $self.timers,
next_index: $self.next_index,
base_idle_time: $self.base_idle_time,
Expand Down Expand Up @@ -138,6 +151,22 @@ where
with_module!(self, (self.module, other))
}

/// Set whether or not we reset the idle timer once a suspend was detected. This only affects
/// main/main_async.
pub fn set_detect_sleep(&mut self, value: bool) {
self.detect_sleep = value;
}
/// Get whether or not we reset the idle timer once a suspend was detected
pub fn detect_sleep(&self) -> bool {
self.detect_sleep
}
/// Set whether or not we reset the idle timer once a suspend was detected. This only affects
/// main/main_async. This is the chainable version of `set_detect_sleep`.
pub fn with_detect_sleep(mut self, value: bool) -> Self {
self.detect_sleep = value;
self
}

/// Returns an immutable list of all timers
pub fn timers(&self) -> &Vec<T> {
&self.timers
Expand Down Expand Up @@ -430,6 +459,8 @@ where
Action::Sleep(delay) => {
trace!("Sleeping for {:?}", delay);

let sleep_start = Instant::now();

// This sleep, unlike `thread::sleep`, will stop for signals.
unsafe {
libc::nanosleep(
Expand All @@ -446,6 +477,16 @@ where
ptr::null_mut(),
);
}

if let Some(time_difference) = sleep_start.elapsed().checked_sub(delay) {
if time_difference >= Duration::from_secs(3) && self.detect_sleep {
info!(
"We slept {:?} longer than expected - has the computer been suspended?",
time_difference,
);
self.reset()?;
}
}
},
Action::Forever => {
warn!("xidlehook has not, and will never get, anything to do");
Expand All @@ -471,12 +512,24 @@ where
Action::Sleep(delay) => {
trace!("Sleeping for {:?}", delay);

let sleep_start = Instant::now();

#[cfg(feature = "async-std")]
async_std::task::sleep(delay).await;
#[cfg(feature = "tokio")]
if cfg!(not(feature = "async-std")) {
tokio::time::delay_for(delay).await;
}

if let Some(time_difference) = sleep_start.elapsed().checked_sub(delay) {
if time_difference >= Duration::from_secs(3) && self.detect_sleep {
info!(
"We slept {:?} longer than expected - has the computer been suspended?",
time_difference,
);
self.reset()?;
}
}
},
Action::Forever => {
trace!("Nothing to do");
Expand Down
17 changes: 11 additions & 6 deletions xidlehook-daemon/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ pub struct Opt {
/// videos.
#[structopt(long, conflicts_with("print"))]
pub not_when_fullscreen: bool,
/// Detect when the system wakes up from a suspend and reset the idle timer
#[structopt(long, conflicts_with("print"))]
pub detect_sleep: bool,

/// The duration is the number of seconds of inactivity which
/// should trigger this timer.
Expand All @@ -67,15 +70,15 @@ pub struct Opt {
#[structopt(long, conflicts_with("print"), required_unless("print"), value_names = &["duration", "command", "canceller"])]
pub timer: Vec<String>,

/// Don't invoke the timer when any audio is playing (PulseAudio specific)
#[cfg(feature = "pulse")]
#[structopt(long, conflicts_with("print"))]
pub not_when_audio: bool,

/// Listen to a unix socket at this address for events.
/// Each event is one line of JSON data.
#[structopt(long, conflicts_with("print"))]
pub socket: Option<String>,

/// Don't invoke the timer when any audio is playing (PulseAudio specific)
#[cfg(feature = "pulse")]
#[structopt(long, conflicts_with("print"))]
pub not_when_audio: bool,
}

#[tokio::main]
Expand Down Expand Up @@ -126,7 +129,9 @@ async fn main() -> xidlehook_core::Result<()> {
}
}

let xidlehook = Xidlehook::new(timers).register(modules);
let xidlehook = Xidlehook::new(timers)
.register(modules)
.with_detect_sleep(opt.detect_sleep);
App {
opt,
xcb,
Expand Down

0 comments on commit 6647a5f

Please sign in to comment.