KarsMulder / evsieve

A utility for mapping events from Linux event devices.
GNU General Public License v2.0
199 stars 11 forks source link

2 instances working simultaneously #4

Closed positiveway closed 2 years ago

positiveway commented 2 years ago

Hi, I want to implement key remapping with layouts. Basically if dev_layout is active, keys would be remapped c -> ctrl+c, v -> ctrl+v, l -> ctrl+alt+l, etc. If another layout is active, different mapping works.

The best way to implement this that I can think of is to have a "control switcher" instance that always running and on the press of special keys (like "f8", 'f10") executes bash script. Bash script would kill the previous instance of evsieve and run another one with a different layout (set of arguments).

The problem is there always gonna be two instances running: "control switcher" and "layout handler". Does evsieve take exclusive control when running thus one of the two instances will just stop working? Maybe there is a better simpler way to implement such functionality?

KarsMulder commented 2 years ago

Nothing inherently prevents multiple instances of evsieve from running simultaneously, but the main problem in this scenario is that you want one of the two instances to "grab" the input device to prevent X/Wayland reading events from both the real and virtual device, and this grabbing simultaneously prevents a second instance of evsieve from reading from the same input device as well.

In your specific use case of having different maps, this is best accomplished with toggles and domains. For example, the following script will map c -> ctrl+c, v -> ctrl+v, l -> ctrl+alt+l after the user presses F10 and goes back to directly mimicking the input keyboard after pressing F8:

evsieve --input /dev/input/by-id/keyboard grab \
        --hook key:f8  toggle=:1 \
        --hook key:f10 toggle=:2 \
        --toggle "" @norm_layout @dev_layout \
        --map key:c@dev_layout key:leftctrl key:c \
        --map key:v@dev_layout key:leftctrl key:v \
        --map key:l@dev_layout key:leftctrl key:leftalt key:l \
        --output

This is analogous to the example "Toggle events between two virtual devices" in the README, except instead of using domains to decide whether a given --output arguments accepts given events, they are used to decide whether certain maps apply to given events.


In case somebody else reads this issue: if you absolutely must run two instances of evsieve on the same input device, and you must grab that input device, I think the best solution would be to run a third instance which duplicates that input device to two virtual devices:

evsieve --input /dev/input/by-id/keyboard grab \
        --map "" @out-1 @out-2 \
        --output @out-1 create-link=/dev/input/by-id/virtual-keyboard-1 \
        --output @out-2 create-link=/dev/input/by-id/virtual-keyboard-2

You can then pass /dev/input/by-id/virtual-keyboard-1 to your first instance and /dev/input/by-id/virtual-keyboard-2 to your second instance.

positiveway commented 2 years ago

Thank you so much for the "toggle" example! That is exactly what I was looking for.

positiveway commented 2 years ago

I think the example with multiple layouts should be added to readme. It would be helpful for many cases.

KarsMulder commented 2 years ago

I added an example "Change how keys are mapped at runtime" to the README.