Implement dialog timeout & timeout bar

This commit is contained in:
Brian Tarricone 2022-05-03 23:47:06 -07:00
parent 2e86445c3d
commit 832b381421
2 changed files with 61 additions and 18 deletions

View File

@ -45,3 +45,9 @@ run: build-dev
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
HELPER_DIR=target/debug \
cargo run --bin bscreensaver
run-dialog:
RUST_BACKTRACE=1 \
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
BSCREENSAVER_DIALOG_STANDALONE=1 \
cargo run --bin bscreensaver-dialog-gtk3

View File

@ -4,10 +4,13 @@ use gethostname::gethostname;
use glib::GString;
use gtk::{prelude::*, Button, Entry, Label, Plug, Window};
use log::{debug, error};
use std::{io::{self, Write}, process::exit, thread};
use std::{io::{self, Write}, process::exit, rc::Rc, thread, time::Duration};
use bscreensaver_util::init_logging;
const DIALOG_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
const DIALOG_TIMEOUT: Duration = Duration::from_secs(60);
fn main() -> anyhow::Result<()> {
init_logging("BSCREENSAVER_DIALOG_GTK3_LOG");
@ -183,14 +186,14 @@ fn main() -> anyhow::Result<()> {
label_sg.add_widget(&label);
hbox.pack_start(&label, false, true, 8);
let password_box = Entry::builder()
let password_box = Rc::new(Entry::builder()
.visibility(false)
.input_purpose(gtk::InputPurpose::Password)
.activates_default(true)
.width_chars(25)
.build();
entry_sg.add_widget(&password_box);
hbox.pack_start(&password_box, true, true, 8);
.build());
entry_sg.add_widget(&*password_box);
hbox.pack_start(&*password_box, true, true, 8);
password_box.connect_key_press_event(|_, ev| {
if ev.keyval().name() == Some(GString::from("Escape")) {
exit(1);
@ -208,25 +211,59 @@ fn main() -> anyhow::Result<()> {
let button = Button::builder()
.label("Unlock")
.build();
button.connect_clicked(move |button| {
button.set_sensitive(false);
password_box.set_sensitive(false);
{
let password_box = Rc::clone(&password_box);
button.connect_clicked(move |button| {
button.set_sensitive(false);
password_box.set_sensitive(false);
let username = username.clone();
let password = password_box.text().to_string();
let username = username.clone();
let password = password_box.text().to_string();
thread::spawn(move || {
if authenticate(&username, &password) {
exit(0);
} else {
exit(-1);
}
thread::spawn(move || {
if authenticate(&username, &password) {
exit(0);
} else {
exit(-1);
}
});
});
});
}
hbox.pack_end(&button, false, true, 8);
button.set_can_default(true);
button.set_has_default(true);
let timer = Rc::new(gtk::ProgressBar::builder()
.orientation(gtk::Orientation::Horizontal)
.fraction(1.0)
.show_text(false)
.can_focus(false)
.margin(2)
.build());
top_vbox.pack_end(&*timer, false, false, 0);
{
let timer = Rc::clone(&timer);
let delta = (DIALOG_UPDATE_INTERVAL.as_millis() as f64) / (DIALOG_TIMEOUT.as_millis() as f64);
gtk::glib::source::timeout_add_local(DIALOG_UPDATE_INTERVAL, move || {
let new_fraction = timer.fraction() - delta;
if new_fraction <= 0.0 {
exit(1);
}
timer.set_fraction(new_fraction);
Continue(true)
});
}
{
let timer = Rc::clone(&timer);
password_box.connect_key_press_event(move |_, _| {
let new_fraction = timer.fraction() + 0.05;
timer.set_fraction(if new_fraction >= 1.0 { 1.0 } else { new_fraction });
Inhibit(false)
});
}
dialog.show_all();
gtk::main();