screen_wake_lock/
lib.rs

1//! screen-wake-lock: minimal cross-platform "keep screen awake" guard.
2//!
3//! Usage:
4//! ```no_run
5//! let lock = screen_wake_lock::ScreenWakeLock::acquire("Playing video")?;
6//! // keep running...
7//! drop(lock); // screen can sleep again
8//! # Ok::<(), screen_wake_lock::Error>(())
9//! ```
10
11use cfg_if::cfg_if;
12
13cfg_if! {
14    if #[cfg(target_os = "windows")] {
15        mod windows;
16        use windows as sys;
17    } else if #[cfg(target_os = "macos")] {
18        mod macos;
19        use macos as sys;
20    } else if #[cfg(target_os = "linux")] {
21        mod linux;
22        use linux as sys;
23    } else {
24        compile_error!("screen-wake-lock only supports Windows, macOS, and Linux.");
25    }
26}
27
28/// Error type for wake lock acquisition.
29#[derive(Debug, thiserror::Error)]
30pub enum Error {
31    /// Generic OS error (e.g. Win32 GetLastError).
32    #[error("OS error: {0}")]
33    Os(String),
34    /// D-Bus error (Linux).
35    #[error("D-Bus error: {0}")]
36    Dbus(String),
37    /// Not supported in the current environment (Linux without a session bus/service).
38    #[error("Unsupported: {0}")]
39    Unsupported(String),
40}
41
42/// Options for Linux (ignored on Windows/macOS).
43#[derive(Clone, Debug)]
44pub struct LinuxOptions {
45    /// D-Bus "application name" / app_id (often reverse-DNS). If None, a default is used.
46    pub application_id: Option<String>,
47    /// Human readable reason. If None, the `reason` passed to `acquire*` is used.
48    pub reason: Option<String>,
49}
50
51impl Default for LinuxOptions {
52    fn default() -> Self {
53        Self {
54            application_id: None,
55            reason: None,
56        }
57    }
58}
59
60/// Guard that keeps the **display** from idling/sleeping while alive.
61pub struct ScreenWakeLock {
62    inner: sys::Inner,
63}
64
65impl ScreenWakeLock {
66    /// Acquire a screen wake lock with a reason string.
67    pub fn acquire(reason: impl Into<String>) -> Result<Self, Error> {
68        Self::acquire_with_linux_options(reason, LinuxOptions::default())
69    }
70
71    /// Acquire, with extra Linux-specific options (safe to call on all platforms).
72    pub fn acquire_with_linux_options(
73        reason: impl Into<String>,
74        linux: LinuxOptions,
75    ) -> Result<Self, Error> {
76        let reason = reason.into();
77        let inner = sys::acquire(&reason, linux)?;
78        Ok(Self { inner })
79    }
80
81    /// Best-effort check (Linux: checks for a usable inhibitor service).
82    pub fn is_supported() -> bool {
83        sys::is_supported()
84    }
85
86    /// Explicitly release early (also happens automatically on Drop).
87    pub fn release(self) {
88        drop(self);
89    }
90}
91
92impl Drop for ScreenWakeLock {
93    fn drop(&mut self) {
94        sys::release(&mut self.inner);
95    }
96}