Codify dialog exit statuses and make them less error-prone

This commit is contained in:
Brian Tarricone 2022-05-30 17:47:56 -07:00
parent 762fdc3912
commit 32cb674e7a
2 changed files with 31 additions and 15 deletions

View File

@ -4,9 +4,9 @@ use gethostname::gethostname;
use glib::{GString, clone, SourceId}; use glib::{GString, clone, SourceId};
use gtk::{prelude::*, Button, Entry, Label, Plug, Window}; use gtk::{prelude::*, Button, Entry, Label, Plug, Window};
use log::{debug, error, warn}; use log::{debug, error, warn};
use std::{io::{self, Write}, process::exit, thread, time::Duration}; use std::{io::{self, Write}, thread, time::Duration};
use bscreensaver_util::{init_logging, settings::Configuration, desktop::NewLoginCommand}; use bscreensaver_util::{init_logging, DialogExitStatus, settings::Configuration, desktop::NewLoginCommand};
const DIALOG_UPDATE_INTERVAL: Duration = Duration::from_millis(100); const DIALOG_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
const DIALOG_TIMEOUT: Duration = Duration::from_secs(60); const DIALOG_TIMEOUT: Duration = Duration::from_secs(60);
@ -70,7 +70,7 @@ fn main() -> anyhow::Result<()> {
let plug_window = match plug.window().unwrap().downcast::<X11Window>() { let plug_window = match plug.window().unwrap().downcast::<X11Window>() {
Err(err) => { Err(err) => {
error!("Failed to find XID of unlock dialog window: {}", err); error!("Failed to find XID of unlock dialog window: {}", err);
exit(2); DialogExitStatus::OtherError.exit();
}, },
Ok(w) => w, Ok(w) => w,
}; };
@ -85,7 +85,7 @@ fn main() -> anyhow::Result<()> {
let mut out_locked = out.lock(); let mut out_locked = out.lock();
if let Err(err) = out_locked.write_all(&xid_buf).and_then(|_| out_locked.flush()) { if let Err(err) = out_locked.write_all(&xid_buf).and_then(|_| out_locked.flush()) {
error!("Failed to write XID to stdout: {}", err); error!("Failed to write XID to stdout: {}", err);
exit(2); DialogExitStatus::OtherError.exit();
}; };
}); });
@ -102,7 +102,7 @@ fn main() -> anyhow::Result<()> {
// an examination of the gtk source suggesting that the header should send // an examination of the gtk source suggesting that the header should send
// a delete-event to the toplevel (which should be the plug) when the close // a delete-event to the toplevel (which should be the plug) when the close
// button is clicked. For some reason, though, we never get the delete-event. // button is clicked. For some reason, though, we never get the delete-event.
dialog.connect_delete_event(|_, _| exit(1)); dialog.connect_delete_event(|_, _| DialogExitStatus::AuthCanceled.exit());
dialog.connect_realize(|_| debug!("DIALOG REALIZED")); dialog.connect_realize(|_| debug!("DIALOG REALIZED"));
dialog.connect_map(|_| debug!("DIALOG MAPPED")); dialog.connect_map(|_| debug!("DIALOG MAPPED"));
dialog.connect_unmap(|_| debug!("DIALOG UNMAPPED")); dialog.connect_unmap(|_| debug!("DIALOG UNMAPPED"));
@ -164,14 +164,14 @@ fn main() -> anyhow::Result<()> {
.build(); .build();
vbox.pack_start(&auth_status_label, false, false, 0); vbox.pack_start(&auth_status_label, false, false, 0);
rx.attach(None, clone!(@strong auth_status_label => move |(exit_status, auth_dots_id): (i32, SourceId)| { rx.attach(None, clone!(@strong auth_status_label => move |(exit_status, auth_dots_id): (DialogExitStatus, SourceId)| {
auth_dots_id.remove(); auth_dots_id.remove();
if exit_status != 0 { if exit_status != DialogExitStatus::AuthSucceeded {
auth_status_label.set_label("Authentication Failed!"); auth_status_label.set_label("Authentication Failed!");
auth_status_label.set_opacity(1.0); auth_status_label.set_opacity(1.0);
glib::timeout_add_seconds_local_once(1, move || exit(exit_status)); glib::timeout_add_seconds_local_once(1, move || exit_status.exit());
} else { } else {
exit(exit_status); exit_status.exit();
} }
glib::Continue(true) glib::Continue(true)
})); }));
@ -232,7 +232,7 @@ fn main() -> anyhow::Result<()> {
hbox.pack_start(&password_box, true, true, 8); hbox.pack_start(&password_box, true, true, 8);
password_box.connect_key_press_event(|_, ev| { password_box.connect_key_press_event(|_, ev| {
if ev.keyval().name() == Some(GString::from("Escape")) { if ev.keyval().name() == Some(GString::from("Escape")) {
exit(1); DialogExitStatus::AuthCanceled.exit();
} }
gtk::Inhibit(false) gtk::Inhibit(false)
}); });
@ -254,7 +254,7 @@ fn main() -> anyhow::Result<()> {
if let Err(err) = new_login_command.run() { if let Err(err) = new_login_command.run() {
warn!("Failed to run new login command: {}", err); warn!("Failed to run new login command: {}", err);
} else { } else {
exit(1); DialogExitStatus::OtherError.exit();
} }
}); });
}); });
@ -282,13 +282,13 @@ fn main() -> anyhow::Result<()> {
let tx = tx.clone(); let tx = tx.clone();
thread::spawn(move || { thread::spawn(move || {
let status = if authenticate(&username, &password) { let status = if authenticate(&username, &password) {
0 DialogExitStatus::AuthSucceeded
} else { } else {
-1 DialogExitStatus::AuthFailed
}; };
if let Err(err) = tx.send((status, auth_dots_id)) { if let Err(err) = tx.send((status, auth_dots_id)) {
error!("Failed to send exit status to main thread: {}", err); error!("Failed to send exit status to main thread: {}", err);
exit(2); DialogExitStatus::OtherError.exit();
} }
}); });
})); }));
@ -309,7 +309,7 @@ fn main() -> anyhow::Result<()> {
glib::timeout_add_local(DIALOG_UPDATE_INTERVAL, clone!(@strong timer => move || { glib::timeout_add_local(DIALOG_UPDATE_INTERVAL, clone!(@strong timer => move || {
let new_fraction = timer.fraction() - delta; let new_fraction = timer.fraction() - delta;
if new_fraction <= 0.0 { if new_fraction <= 0.0 {
exit(1); DialogExitStatus::AuthTimedOut.exit();
} }
timer.set_fraction(new_fraction); timer.set_fraction(new_fraction);
Continue(true) Continue(true)

View File

@ -6,6 +6,22 @@ pub mod settings;
pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0"; pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0";
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DialogExitStatus {
AuthFailed = -1,
AuthSucceeded = 0,
AuthCanceled = 1,
AuthTimedOut = 2,
OtherError = 3,
}
impl DialogExitStatus {
pub fn exit(&self) -> ! {
std::process::exit(*self as i32);
}
}
pub fn init_logging(env_name: &str) { pub fn init_logging(env_name: &str) {
env_logger::builder() env_logger::builder()
.format_timestamp_millis() .format_timestamp_millis()