evsieve icon indicating copy to clipboard operation
evsieve copied to clipboard

Possible to block regular key output while pressing a hook keyboard combo?

Open oitos opened this issue 3 years ago • 4 comments

I like to use the super key in combination the F row keys for executing scripts. This works fine with evsieve, but with the minor downside that whatever other key gets pressed will also be registered by any open application. For example, if I press Super+F1, then the help menu will (typically) pop up or for Super+F9, it will open the help menu in byobu. Is there some way to suppress regular key output while the keyboard combo is pressed, without losing previous function?

oitos avatar Oct 01 '22 13:10 oitos

Related issue: #7

This is not possible on the stable version of evsieve, but is possbile using the current main branch. If you compile evsieve from the main branch, you can use a combination of the new --withhold argument and the new sequential flag on hooks to do something like this:

evsieve --input /dev/input/by-id/keyboard grab \
        --hook key:leftmeta key:f1 sequential exec-shell="echo Pressed Meta+F1!" \
        --withhold key:f1 \
        --output

The --withhold argument delays the listed keys as long as it is unclear whether or not they will trigger one of the preceding hooks, and drops them if they actually end up triggering them. Thus, in this case key:f1 is dropped if it triggers the hook.

The sequential flag on the hook means that the listed keys must be pressed in that exact order. This means that key:f1 cannot possibly end up triggering the hook unless the meta key is already held down, and therefore the key:f1 events do not get delayed when the meta key isn't pressed.

In your case it isn't really needed because no events are getting delayed in the above script, but I'd like to mention that a single --withhold argument can apply to multiple consecutive hooks:

evsieve --input /dev/input/by-id/keyboard grab \
        --hook key:leftmeta key:f1 sequential exec-shell="echo Pressed Meta+F1!" \
        --hook key:leftmeta key:f2 sequential exec-shell="echo Pressed Meta+F2!" \
        --hook key:leftmeta key:f3 sequential exec-shell="echo Pressed Meta+F3!" \
        --hook key:leftmeta key:f4 sequential exec-shell="echo Pressed Meta+F4!" \
        --withhold key:f1 key:f2 key:f3 key:f4 \
        --output

KarsMulder avatar Oct 03 '22 15:10 KarsMulder

Thank you for your detailed response and--in general--for your dedication to this project. I've compiled and tested with the arguments you have suggested. I had to play around with the different system to see how it works in practice. It almost solves the issue I have described, but unfortunately not without a drawback.

These are my findings: Testing just in XFCE (where the Super key has no critical role), this seems to work just perfectly. However, in a Windows guest the Super button will get sent after the script is executed, resulting in a reverse situation where the F key doesn't interfere, but the Windows menu pops up. I remembered that Gnome has a similar setup and ran an Ubuntu Live CD to test it there, and it has similar results; after pressing the combo, the Activities menu will be activated.

I took a shot in the dark and tested with --withhold key:leftmeta key:f1 key:.., but that breaks any Win+<KEY> keyboard combination in Windows (some of which are actually useful), such as Win+1 for example. My setup differed to your example only in which script was executed.

So I guess this is as good as it gets presently - or have I perhaps I have overlooked something?

oitos avatar Oct 05 '22 13:10 oitos

This is expected behaviour.

If the Win key is not withheld, then a Win key will reach the virtual device when you press Win+F1.

Suppose you want the Win key to not reach the virtual output device in case you press Win+F1, so you add the key:leftmeta to the --withhold argument. Suppose you press Win. It is not possible to undo writing keys to virtual devices, so we cannot write the Win key to the output device yet since we don't know whether an F1 follows later.

If you then press the A key, the A key reaches the output device while the Win key is still withheld, which causes the Win+A combination not to trigger because the Win key isn't pressed yet as far as the output device is concerned. If Win is released later without receiving an F1 key, the delayed Win event is sent to the output device. The end result is that Win+A effectively results in A+Win.

I don't think there is a solution for your problem right now. I suppose this could be solved if there was a flag/clause for --hook that meant "and no other key other than those listed were pressed" (which would cause the Win event to be sent to the output device upon pressing A). I have not yet decided whether I actually want to add such a flag/clause.

KarsMulder avatar Oct 05 '22 18:10 KarsMulder

Aha, I see. I appreciate the explanation. I understand the hesitation with adding in new layers, but I for one would certainly welcome such a feature. It would make working in OS's that utilise the Super button that much more sweet.

In any case this the --withhold feature frees up a few more F keys that would otherwise be causing unwanted actions. Having the Start menu pop up in Windows or activating Super in general in other systems is [afaics] only a minor inconvenience.

oitos avatar Oct 06 '22 11:10 oitos