Don't forward enter or escape to unlock window on first event
If the user presses enter or escape in order to get the unlock dialog to show in the first place, forwarding that event to the dialog will only cause it to close immediately. Also took the opportunity to clean up the dependencies where I have my own patches. I'm now using the cargo 'patch' section so that the dependencies specified in the individual Cargo.toml files are clean.
This commit is contained in:
@ -20,6 +20,7 @@ bscreensaver-util = { path = "../util" }
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
nix = "0.23"
|
||||
# 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"] }
|
||||
x11 = "2.19"
|
||||
xcb = { version = "1", features = ["randr", "xkb", "xfixes", "xinput"] }
|
||||
xcb-xembed = { path = "../xcb-xembed" }
|
||||
xkb = { version = "0.2", features = ["x11"] }
|
||||
|
@ -112,7 +112,7 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
let (conn, screen_num) = xcb::Connection::connect_with_extensions(
|
||||
None,
|
||||
&[xcb::Extension::RandR, xcb::Extension::XFixes, xcb::Extension::Input],
|
||||
&[xcb::Extension::RandR, xcb::Extension::XFixes, xcb::Extension::Input, xcb::Extension::Xkb],
|
||||
&[]
|
||||
)?;
|
||||
let setup = conn.get_setup();
|
||||
@ -121,6 +121,8 @@ fn main() -> anyhow::Result<()> {
|
||||
init_xfixes(&conn)?;
|
||||
init_xinput(&conn)?;
|
||||
init_randr(&conn)?;
|
||||
xkb::x11::setup(&conn, xkb::x11::MIN_MAJOR_XKB_VERSION, xkb::x11::MIN_MINOR_XKB_VERSION, xkb::x11::NO_FLAGS)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to initialize XKB extension"))?;
|
||||
create_command_window(&conn, &screen)?;
|
||||
|
||||
let command_atoms = CommandAtoms {
|
||||
@ -740,6 +742,20 @@ fn start_unlock_dialog<'a>(conn: &'a xcb::Connection, state: &State<'a>, trigger
|
||||
|
||||
show_cursor(conn, state);
|
||||
|
||||
let trigger_event = match trigger_event {
|
||||
Some(xcb::Event::X(x::Event::KeyPress(ev))) => match keysym_for_keypress(conn, &ev) {
|
||||
Err(err) => {
|
||||
warn!("Failed to get keysym for key press event: {}", err);
|
||||
Some(xcb::Event::X(x::Event::KeyPress(ev)))
|
||||
},
|
||||
Ok(Some(keysym)) if keysym == xkb::key::KP_Enter || keysym == xkb::key::ISO_Enter || keysym == xkb::key::Return || keysym == xkb::key::Escape =>
|
||||
// don't forward an <enter> or <esc> to the dialog, as that will make it activate/close immediately
|
||||
None,
|
||||
_ => Some(xcb::Event::X(x::Event::KeyPress(ev))),
|
||||
},
|
||||
te => te,
|
||||
};
|
||||
|
||||
let mut child = Command::new(format!("{}/{}", env!("HELPER_DIR"), state.config.dialog_backend.binary_name()))
|
||||
.stdout(Stdio::piped())
|
||||
.spawn()?;
|
||||
@ -1012,3 +1028,14 @@ fn kill_child_processes(state: &mut State) -> anyhow::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn keysym_for_keypress(conn: &xcb::Connection, ev: &x::KeyPressEvent) -> anyhow::Result<Option<xkb::Keysym>> {
|
||||
let ctx = xkb::Context::new(xkb::context::Flags::NO_FLAGS);
|
||||
let device = xkb::x11::device(conn)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to get xkb device"))?;
|
||||
let keymap = xkb::x11::keymap(conn, device, &ctx, xkb::keymap::compile::Flags::NO_FLAGS)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to get xkb keymap"))?;
|
||||
let state = xkb::x11::state(conn, device, &keymap)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to get xkb state"))?;
|
||||
Ok(state.key(ev.detail()).sym())
|
||||
}
|
||||
|
Reference in New Issue
Block a user