InputBot icon indicating copy to clipboard operation
InputBot copied to clipboard

Key is being intercepted on press

Open emhagman opened this issue 4 years ago • 5 comments

Hi!

Thanks for making this lib :)

I am running into an issue where if I a bind to, say, AKey, using AKey::bind the input is always intercepted. I saw a similar thread with the opposite problem where the input was not being intercepted so I wasn't sure if that was ever changed to intercept the input by default? I am using Linux w/ X11.

To be clear:

fn main() {
    AKey.bind(|| {
        println!("a has been pressed");
    });
    handle_input_events();
}

This very simple example will print a has been pressed in the terminal but then my a key no longer works for typing anything because it seems that the program is preventing the default key action.

As a side note, would it be possible to have an API where we could decide whether to intercept the key or not?

AKey.bind(|event| {
    if ... {
        event.intercept();
    } else {
        // do something else
    }
});

emhagman avatar Jul 14 '20 18:07 emhagman

@emhagman Hi, thanks for your interest in the library!

Currently on Linux the events listened to by InputBot get "consumed" and are always hidden from the system, but on Windows they never get consumed.

I like the idea you proposed at the bottom for making it optional whether and event should be consumed and then hidden or not.

I am not sure how exactly this would be implemented though. If you look in the function here, https://github.com/obv-mikhail/InputBot/blob/master/src/linux/mod.rs#L179, I think there might be some call to libinput that can be modified so that the events won't be consumed.

Alternatively, it might be possible to just rethrow the consumed event as a new one of same type, but marked somehow to be ignored by InputBot. This would additionally solve the issue of binds being triggered by events produced by sending events with InputBot itself.

obv-mikhail avatar Jul 15 '20 01:07 obv-mikhail

@obv-mikhail Thanks for taking the time to respond. I actually took a look at input (libinput for Rust) that you are using and their default 0.5.0 example is not consuming the event (I made a small POC to test it). There isn't much documentation but I'll let you know if I can figure it out

emhagman avatar Jul 15 '20 18:07 emhagman

@emhagman good catch about the 0.5.0 example! I upgraded all the dependencies in InputBot, and it looks like events are no longer consumed. Still needs to be made configurable though..

obv-mikhail avatar Jul 16 '20 04:07 obv-mikhail

Do you have any ideas on how to consume the individual event?

After doing more research, it looks like we can use nix to do this but only for an entire input device, not a single event. https://docs.rs/nix/0.17.0/nix/sys/ioctl/index.html in combination with EVIOCGRAB or using https://ndesh26.github.io/evdev-rs/evdev_rs/struct.Device.html#method.grab

The equivalent of ioctl(fd, EVIOCGRAB, 1); in C.

This prevents all other programs (including the kernel) from reading input, but I haven't been able to find anything else.

EDIT: After doing more research, there is also:

https://wayland.freedesktop.org/libinput/doc/latest/configuration.html#send-events-mode https://github.com/Smithay/input.rs/blob/1afe2ee868c89c62c9920a760313609d612d0a1f/src/device.rs#L1283 config_send_events_mode with SendEventsMode::DISABLED with libinput

emhagman avatar Jul 16 '20 17:07 emhagman

any progress yet? Instead of not consuming the key event, I want to cancel the input event cause I'm gonna use the letter key as function key. But now when I press them, the letters were typed too. I think blocking the input event should be the default behavior? If you want, just call the input event by yourself.

seyoatda avatar Jul 25 '22 06:07 seyoatda