Add 'New Login' button to unlock dialog
This commit is contained in:
parent
832b381421
commit
92504d279a
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -263,10 +263,8 @@ dependencies = [
|
|||||||
"humantime",
|
"humantime",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"toml",
|
|
||||||
"xcb",
|
"xcb",
|
||||||
"xcb-xembed",
|
"xcb-xembed",
|
||||||
"xdg",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -316,6 +314,7 @@ dependencies = [
|
|||||||
"gtk-sys",
|
"gtk-sys",
|
||||||
"log",
|
"log",
|
||||||
"pam",
|
"pam",
|
||||||
|
"shell-words",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -339,11 +338,14 @@ dependencies = [
|
|||||||
name = "bscreensaver-util"
|
name = "bscreensaver-util"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
"toml",
|
||||||
"xcb",
|
"xcb",
|
||||||
|
"xdg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1508,6 +1510,12 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shell-words"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
|
@ -15,4 +15,4 @@ gdk-sys = "0.15"
|
|||||||
gdkx11 = "0.15"
|
gdkx11 = "0.15"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pam = "0.7"
|
pam = "0.7"
|
||||||
#x11 = "2.19"
|
shell-words = "1"
|
||||||
|
@ -3,10 +3,10 @@ use gdkx11::X11Window;
|
|||||||
use gethostname::gethostname;
|
use gethostname::gethostname;
|
||||||
use glib::GString;
|
use glib::GString;
|
||||||
use gtk::{prelude::*, Button, Entry, Label, Plug, Window};
|
use gtk::{prelude::*, Button, Entry, Label, Plug, Window};
|
||||||
use log::{debug, error};
|
use log::{debug, error, warn};
|
||||||
use std::{io::{self, Write}, process::exit, rc::Rc, thread, time::Duration};
|
use std::{io::{self, Write}, process::{exit, Command}, rc::Rc, thread, time::Duration};
|
||||||
|
|
||||||
use bscreensaver_util::init_logging;
|
use bscreensaver_util::{init_logging, load_configuration};
|
||||||
|
|
||||||
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);
|
||||||
@ -14,6 +14,12 @@ const DIALOG_TIMEOUT: Duration = Duration::from_secs(60);
|
|||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
init_logging("BSCREENSAVER_DIALOG_GTK3_LOG");
|
init_logging("BSCREENSAVER_DIALOG_GTK3_LOG");
|
||||||
|
|
||||||
|
let mut new_login_command = load_configuration()?.and_then(|config_toml| {
|
||||||
|
config_toml.get("new-login-command")
|
||||||
|
.and_then(|nlc| nlc.as_str().map(|s| s.to_string()))
|
||||||
|
.map(|nlc| shell_words::split(&nlc))
|
||||||
|
}).transpose()?.filter(|nlc| !nlc.is_empty());
|
||||||
|
|
||||||
let standalone = std::env::var("BSCREENSAVER_DIALOG_STANDALONE").is_ok();
|
let standalone = std::env::var("BSCREENSAVER_DIALOG_STANDALONE").is_ok();
|
||||||
|
|
||||||
unsafe { glib::log_writer_default_set_use_stderr(true) };
|
unsafe { glib::log_writer_default_set_use_stderr(true) };
|
||||||
@ -208,13 +214,30 @@ fn main() -> anyhow::Result<()> {
|
|||||||
.build();
|
.build();
|
||||||
vbox.pack_start(&hbox, true, true, 2);
|
vbox.pack_start(&hbox, true, true, 2);
|
||||||
|
|
||||||
let button = Button::builder()
|
if let Some(new_login_command) = new_login_command.take() {
|
||||||
|
let new_login_button = Button::builder()
|
||||||
|
.label("New Login")
|
||||||
|
.build();
|
||||||
|
new_login_button.connect_clicked(move |_| {
|
||||||
|
let cmd = &new_login_command[0];
|
||||||
|
let empty = Vec::<String>::new();
|
||||||
|
let args = if new_login_command.len() > 1 { &new_login_command[1..] } else { &empty };
|
||||||
|
if let Err(err) = Command::new(cmd).args(args).spawn() {
|
||||||
|
warn!("Failed to run new login command: {}", err);
|
||||||
|
} else {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hbox.pack_start(&new_login_button, false, true, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
let unlock_button = Button::builder()
|
||||||
.label("Unlock")
|
.label("Unlock")
|
||||||
.build();
|
.build();
|
||||||
{
|
{
|
||||||
let password_box = Rc::clone(&password_box);
|
let password_box = Rc::clone(&password_box);
|
||||||
button.connect_clicked(move |button| {
|
unlock_button.connect_clicked(move |unlock_button| {
|
||||||
button.set_sensitive(false);
|
unlock_button.set_sensitive(false);
|
||||||
password_box.set_sensitive(false);
|
password_box.set_sensitive(false);
|
||||||
|
|
||||||
let username = username.clone();
|
let username = username.clone();
|
||||||
@ -229,9 +252,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
hbox.pack_end(&button, false, true, 8);
|
hbox.pack_end(&unlock_button, false, true, 8);
|
||||||
button.set_can_default(true);
|
unlock_button.set_can_default(true);
|
||||||
button.set_has_default(true);
|
unlock_button.set_has_default(true);
|
||||||
|
|
||||||
let timer = Rc::new(gtk::ProgressBar::builder()
|
let timer = Rc::new(gtk::ProgressBar::builder()
|
||||||
.orientation(gtk::Orientation::Horizontal)
|
.orientation(gtk::Orientation::Horizontal)
|
||||||
|
@ -20,8 +20,6 @@ bscreensaver-util = { path = "../util" }
|
|||||||
humantime = "2"
|
humantime = "2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nix = "0.23"
|
nix = "0.23"
|
||||||
toml = "0.5"
|
|
||||||
# git source needed until extension event error resolution fix is released
|
# git source needed until extension event error resolution fix is released
|
||||||
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "d09b5f91bc07d56673f1bc0d6c7ecd72b5ff7b3e", features = ["randr", "xfixes", "xinput"] }
|
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "d09b5f91bc07d56673f1bc0d6c7ecd72b5ff7b3e", features = ["randr", "xfixes", "xinput"] }
|
||||||
xcb-xembed = { path = "../xcb-xembed" }
|
xcb-xembed = { path = "../xcb-xembed" }
|
||||||
xdg = "2"
|
|
||||||
|
@ -15,7 +15,7 @@ use nix::{
|
|||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
ffi::CString,
|
ffi::CString,
|
||||||
fs::{read_link, File},
|
fs::read_link,
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
os::{
|
os::{
|
||||||
linux::process::{ChildExt, CommandExt, PidFd},
|
linux::process::{ChildExt, CommandExt, PidFd},
|
||||||
@ -277,19 +277,11 @@ fn main() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
fn parse_config() -> anyhow::Result<Configuration> {
|
fn parse_config() -> anyhow::Result<Configuration> {
|
||||||
use humantime::parse_duration;
|
use humantime::parse_duration;
|
||||||
use toml::Value;
|
|
||||||
|
|
||||||
match xdg::BaseDirectories::new()?.find_config_file("bscreensaver.toml") {
|
|
||||||
None => Ok(Configuration::default()),
|
|
||||||
Some(config_path) => {
|
|
||||||
let mut f = File::open(config_path)?;
|
|
||||||
let mut config = String::new();
|
|
||||||
f.read_to_string(&mut config)?;
|
|
||||||
drop(f);
|
|
||||||
|
|
||||||
let config_toml = config.parse::<Value>()?;
|
|
||||||
let mut config = Configuration::default();
|
|
||||||
|
|
||||||
|
let mut config = Configuration::default();
|
||||||
|
match load_configuration()? {
|
||||||
|
None => Ok(config),
|
||||||
|
Some(config_toml) => {
|
||||||
config.lock_timeout = match config_toml.get("lock-timeout") {
|
config.lock_timeout = match config_toml.get("lock-timeout") {
|
||||||
None => config.lock_timeout,
|
None => config.lock_timeout,
|
||||||
Some(val) => parse_duration(val.as_str().ok_or(anyhow!("'lock-timeout' must be a duration string like '10m' or '90s'"))?)?,
|
Some(val) => parse_duration(val.as_str().ok_or(anyhow!("'lock-timeout' must be a duration string like '10m' or '90s'"))?)?,
|
||||||
|
@ -6,8 +6,11 @@ edition = "2021"
|
|||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1"
|
||||||
clap = "3"
|
clap = "3"
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
toml = "0.5"
|
||||||
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "d09b5f91bc07d56673f1bc0d6c7ecd72b5ff7b3e", features = ["randr", "screensaver", "xfixes"] }
|
xcb = { git = "https://github.com/rust-x-bindings/rust-xcb", rev = "d09b5f91bc07d56673f1bc0d6c7ecd72b5ff7b3e", features = ["randr", "screensaver", "xfixes"] }
|
||||||
|
xdg = "2"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{ffi::CStr, io};
|
use std::{ffi::CStr, fs::File, io::{self, Read}};
|
||||||
|
use toml::Value;
|
||||||
use xcb::x;
|
use xcb::x;
|
||||||
|
|
||||||
pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0";
|
pub const BSCREENSAVER_WM_CLASS: &[u8] = b"bscreensaver\0Bscreensaver\0";
|
||||||
@ -10,6 +11,21 @@ pub fn init_logging(env_name: &str) {
|
|||||||
.init();
|
.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_configuration() -> anyhow::Result<Option<Value>> {
|
||||||
|
match xdg::BaseDirectories::new()?.find_config_file("bscreensaver.toml") {
|
||||||
|
None => Ok(None),
|
||||||
|
Some(config_path) => {
|
||||||
|
let mut f = File::open(config_path)?;
|
||||||
|
let mut config = String::new();
|
||||||
|
f.read_to_string(&mut config)?;
|
||||||
|
drop(f);
|
||||||
|
|
||||||
|
let config_toml = config.parse::<Value>()?;
|
||||||
|
Ok(Some(config_toml))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_atom(conn: &xcb::Connection, name: &[u8]) -> xcb::Result<x::Atom> {
|
pub fn create_atom(conn: &xcb::Connection, name: &[u8]) -> xcb::Result<x::Atom> {
|
||||||
let cookie = conn.send_request(&x::InternAtom {
|
let cookie = conn.send_request(&x::InternAtom {
|
||||||
only_if_exists: false,
|
only_if_exists: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user