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:
2022-05-17 19:44:38 -07:00
parent 9e266894df
commit c3166f0b9c
11 changed files with 266 additions and 43 deletions

View File

@ -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())
}