1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
#[cfg(target_os = "macos")]
mod macos;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "linux")]
mod linux;
use std::fmt;
/// Holds a Win32 error code retrieved from the `GetLastError` Windows API
/// function.
pub type Win32ErrorCode = u32;
/// Screenlocker result.
type Result<T> = std::result::Result<T, Error>;
/// Error information explaining why the screen couldn't be locked.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
/// A Win32 API function reported an error code.
Win32(Win32ErrorCode),
/// The current OS platform is not supported (yet) by screenlocker. Please
/// send a pull request or file an issue if you would like to add support!
UnsupportedPlatform,
/// An error occurred when trying to run a caller specified executable.
ExeIoError {
/// String path of the command that was to be executed, or `None` if the
/// command was invalid UTF8.
cmd: Option<String>,
/// The error kind reported by `std::io::Error` when trying to run this
/// command.
kind: std::io::ErrorKind,
/// The error message reported by `std::io::Error` when trying to run
/// this command.
msg: String,
},
/// A user specified exe returned a non-zero exit code when executed.
NonZeroExit {
/// String path of the command that was to be executed, or `None` if the
/// command was invalid UTF8.
cmd: Option<String>,
/// Exit code returned by the user program after termination. This value
/// is `None` if the program was terminated by a signal instead of
/// normal termination.
exit_code: Option<i32>,
},
/// None of the provided screenlocking programs could be found.
NoExeFound,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Error::Win32(ec) => write!(f, "GetLastResult() returned {}", ec),
Error::UnsupportedPlatform => {
write!(f, "this platform is not supported - please file a bug")
}
Error::ExeIoError { cmd, kind, msg } => {
let cmd_name = match cmd {
Some(cmd) => cmd.clone(),
None => "with invalid utf8 name".to_string(),
};
write!(
f,
"io error {:?} ({}) when running user program {}",
kind, msg, cmd_name
)
}
Error::NonZeroExit { cmd, exit_code } => {
let reason = match exit_code {
Some(exit_code) => {
format!("non-succesful exit-code {}", exit_code)
}
None => "signal termination".to_owned(),
};
let cmd_name = match cmd {
Some(cmd) => cmd.clone(),
None => "with invalid utf8 name".to_string(),
};
write!(f, "{} when running user program {}", reason, cmd_name)
}
Error::NoExeFound => {
write!(f, "none of the provided user programs were found")
}
}
}
}
/// Locks the computer screen by hiding the current desktop, and requiring
/// the user to re-enter their password before continuing.
///
/// # Errors
/// If `lock_screen()` encounters any errors while trying to lock the screen, an
/// error variant will be returned. Macs do report errors, and while possible on
/// Windows it is exceptionally unlikely. Screen locking on Linux could return
/// an error if none of the hard coded screen locking programs exist on the
/// system.
///
/// Please open an issue or create a pull request if the hardcoded Linux list
/// is missing a screen locking program for your distro.
pub fn lock_screen() -> Result<()> {
#[cfg(target_os = "macos")]
return crate::macos::lock_screen_mac();
#[cfg(target_os = "windows")]
return crate::windows::lock_screen_windows();
#[cfg(target_os = "linux")]
return crate::linux::lock_screen_linux();
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
return Err(Error::UnsupportedPlatform);
}