Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

space on release if not part of combination + input lags #49

Closed
LexRiver opened this issue Feb 27, 2021 · 30 comments
Closed

space on release if not part of combination + input lags #49

LexRiver opened this issue Feb 27, 2021 · 30 comments
Labels
environment incompatibility bugs that are impossible for me to track down, key-mapper seems to work correctly feature request

Comments

@LexRiver
Copy link

Hello, I want to bind
Space+J=Left
Space+K=Down
Space+L=Right
Space+I=Up
but
Space=Space
So If I just press down Space and release it, it will send normal Spacebar key " " as expected.
Is it possible with your tool?

@sezanzeb
Copy link
Owner

sezanzeb commented Mar 1, 2021

Is it possible with your tool?

yes

image

Does that fail for you?

@LexRiver
Copy link
Author

LexRiver commented Mar 1, 2021

@sezanzeb thank you for answer
my problem is that "space" is sending anyway before action.
How can I disable sending "space" if that is part of hotkey?

@sezanzeb
Copy link
Owner

sezanzeb commented Mar 1, 2021

ah I see. Mapping key-up wouldn't work because of the usage of is_key_down throughout https://github.com/sezanzeb/key-mapper/blob/main/keymapper/injection/keycode_mapper.py, but a macro can do it. It is however not possible to prevent the output of that macro if another key was pressed.

@sezanzeb
Copy link
Owner

sezanzeb commented Mar 3, 2021

Writing keys on release is h().k(space), I would need a somewhat intuitive macro-function to stop the macro if any key is pressed, so that only the combination is triggered. I also don't know yet how I would implement that stuff.

Maybe via a macro on the combination that takes the triggering key for the mentioned macro as parameter in order to call stop (stop also doesn't exist yet) on it.

e.g.

Space+I: stop(1, 57, 1).m(up, h())
Space: h().k(space)

or maybe as a shorthand that implies an event type of ev_key and a value of 1 and that looks up the code in xmodmap

Space+I: stop(space).m(up, h())

@sezanzeb sezanzeb changed the title Is it possible to bind Space+K ? Writing space on release if not part of a triggered combination Mar 3, 2021
@LexRiver
Copy link
Author

LexRiver commented Mar 4, 2021

I think the solution would be something like this.

   on any key pressed:
        if key is part of some hotkey:
            do not send this key and wait for other key(s)
            if other part of hotkey is pressed then:
                send hotkey result key
                set flag hotkeyPressed = true

    on any key released:
        if key is part of hotkey:
            if not hotkeyPressed:
                send released key

@sezanzeb
Copy link
Owner

sezanzeb commented Mar 4, 2021

just sending the release event without prior down will not write that key. That means e.g. that if a combination of shift+a is mapped and shift also has a function in a game, shift would not do anything anymore. And even if you also inject the down event based on some condition after releasing, the shift would come late whereas people usually want fast reaction times.

Feel free to try to implement a solution that passes all existing tests.

But there are too many open questions and difficulties (how to configure, how to avoid the above problems, keycode_mapper is already quite complex) and it is an uncommon use case, so macros are the only way I would implement this.

@LexRiver
Copy link
Author

@sezanzeb Thank you for pointing me into the right direction.
I was trying xlib, but evdev is much better.

Here is my solution
https://github.com/LexRiver/linux-deep-hotkeys/blob/main/linux-deep-hotkeys.py
You can implement it if you want, but I don't think that it will be popular use case -)

@sezanzeb
Copy link
Owner

I guess plugin support would be cool. But I'm not sure yet about the security implications. Since the daemon is running as root it should only accept plugins that are owned by root, i.e. installed system wide via e.g. sudo pip3 install.

And I need to think of a proper way to configure which plugins should be used

@sezanzeb
Copy link
Owner

sezanzeb commented Apr 25, 2021

with the latest changes this is possible:

image

  • set(a, 0) indicates that the space macro is started
  • set(a, 1) indicates that the combination is triggered
  • a is arbitrarily chosen, you could also call it "foo", "space_flag" or "flag"
  • h() waits until the key is released
  • ifeq(a, 0, k(space)) only writes space if the combination was not triggered, which is indicated by a being 0.
  • h(right) holds down "right" as long as you hold down your key

does that work for you?

@LexRiver
Copy link
Author

@sezanzeb wow! great! that works!
But a bit laggy for me.

I'm just pressing Ctrl+Left, Shift+Right (holding) or Ctrl+Left, Right (holding).
Please see this screen record or download and play.

simplescreenrecorder-2021-04-26_20.57.12-converted.mp4

And that is mine script:

simplescreenrecorder-2021-04-26_21.02.07-converted.mp4

Also your mapping looks a bit hacky -)

set(flag,0).h().ifeq(flag, 0, k(space))
set(flag,1).h(right)

Maybe add a full length command names? something like this:

set(flag, 0); waitKeyRelease(); ifeq(flag, 0, sendKey(space))
set(flag, 1); holdKey(right)

Seems like you are creating your own language, just like AutoHotKey tool for windows -)

@sezanzeb
Copy link
Owner

sezanzeb commented Apr 26, 2021

The editor space is just so constrained, key-mapper would probably need a popup with a multiline text editor when editing macros. That is the only reason why I kept the names so short. I guess nothing is really lost, I can always add longer names at a later point.

Creating a new language for that turned out to be an easy solution actually since it doesn't really need much. It was also fun to make.

Could you please share the preset.json file? It's somewhere in ~/.config/key-mapper/presets/

evtest output for the "mapped" device when reproducing the problem would also be helpful. I.e. after running evtest please use Ctrl+Left and Right, such that the cursor jumps over multiple characters.

@LexRiver
Copy link
Author

preset.json

{
    "mapping": {
        "1,57,1": "set(flag,0).h().ifeq(flag, 0, k(space))",
        "1,57,1+1,38,1": "set(flag,1).h(right)",
        "1,57,1+1,36,1": "set(flag,1).h(left)",
        "1,57,1+1,23,1": "set(flag,1).h(up)",
        "1,57,1+1,37,1": "set(flag,1).h(down)"
    }
}

evtest for mapped device

Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x1 product 0x1 version 0x1
Input device name: "key-mapper SIGMACHIP USB Keyboard mapped"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 57 (KEY_SPACE)
    Event code 103 (KEY_UP)
    Event code 105 (KEY_LEFT)
    Event code 106 (KEY_RIGHT)
    Event code 108 (KEY_DOWN)
  Event type 21 (EV_FF)
Properties:
Testing ... (interrupt to exit)
Event: time 1619540323.044742, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540323.044742, -------------- SYN_REPORT ------------
Event: time 1619540323.132191, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540323.132191, -------------- SYN_REPORT ------------
Event: time 1619540323.572773, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540323.572773, -------------- SYN_REPORT ------------
Event: time 1619540323.700758, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540323.700758, -------------- SYN_REPORT ------------
Event: time 1619540324.140887, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540324.140887, -------------- SYN_REPORT ------------
Event: time 1619540325.364540, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540325.364540, -------------- SYN_REPORT ------------
Event: time 1619540325.524566, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540325.524566, -------------- SYN_REPORT ------------
Event: time 1619540325.604470, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540325.604470, -------------- SYN_REPORT ------------
Event: time 1619540325.780596, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540325.780596, -------------- SYN_REPORT ------------
Event: time 1619540327.268798, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540327.268798, -------------- SYN_REPORT ------------
Event: time 1619540327.492855, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540327.492855, -------------- SYN_REPORT ------------
Event: time 1619540327.580842, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540327.580842, -------------- SYN_REPORT ------------
Event: time 1619540327.772954, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540327.772954, -------------- SYN_REPORT ------------
Event: time 1619540329.100904, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540329.100904, -------------- SYN_REPORT ------------
Event: time 1619540329.373037, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540329.373037, -------------- SYN_REPORT ------------
Event: time 1619540329.452940, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540329.452940, -------------- SYN_REPORT ------------
Event: time 1619540329.629054, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540329.629054, -------------- SYN_REPORT ------------
Event: time 1619540331.005299, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540331.005299, -------------- SYN_REPORT ------------
Event: time 1619540331.253538, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540331.253538, -------------- SYN_REPORT ------------
Event: time 1619540331.349269, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540331.349269, -------------- SYN_REPORT ------------
Event: time 1619540331.541647, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540331.541647, -------------- SYN_REPORT ------------
Event: time 1619540332.909663, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540332.909663, -------------- SYN_REPORT ------------
Event: time 1619540333.142002, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540333.142002, -------------- SYN_REPORT ------------
Event: time 1619540333.221391, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540333.221391, -------------- SYN_REPORT ------------
Event: time 1619540333.421947, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540333.421947, -------------- SYN_REPORT ------------
Event: time 1619540334.733820, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540334.733820, -------------- SYN_REPORT ------------
Event: time 1619540334.989916, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1
Event: time 1619540334.989916, -------------- SYN_REPORT ------------
Event: time 1619540335.085623, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0
Event: time 1619540335.085623, -------------- SYN_REPORT ------------
Event: time 1619540335.277853, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1
Event: time 1619540335.277853, -------------- SYN_REPORT ------------
Event: time 1619540336.582073, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0
Event: time 1619540336.582073, -------------- SYN_REPORT ------------

evtest for "forwarded" for same key combinations

Properties:
Testing ... (interrupt to exit)
Event: time 1619540222.208360, type 17 (EV_LED), code 0 (LED_NUML), value 0
Event: time 1619540222.208360, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70028
Event: time 1619540222.208360, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0
Event: time 1619540222.208360, -------------- SYN_REPORT ------------
Event: time 1619540223.528573, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e2
Event: time 1619540223.528573, type 1 (EV_KEY), code 56 (KEY_LEFTALT), value 1
Event: time 1619540223.528573, -------------- SYN_REPORT ------------
Event: time 1619540223.608567, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7002b
Event: time 1619540223.608567, type 1 (EV_KEY), code 15 (KEY_TAB), value 1
Event: time 1619540223.608567, -------------- SYN_REPORT ------------
Event: time 1619540223.664538, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e2
Event: time 1619540223.664538, type 1 (EV_KEY), code 56 (KEY_LEFTALT), value 0
Event: time 1619540223.664538, -------------- SYN_REPORT ------------
Event: time 1619540223.768339, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7002b
Event: time 1619540223.768339, type 1 (EV_KEY), code 15 (KEY_TAB), value 0
Event: time 1619540223.768339, -------------- SYN_REPORT ------------
Event: time 1619540230.033256, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7002c
Event: time 1619540230.033256, -------------- SYN_REPORT ------------
Event: time 1619540231.009375, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540231.009375, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540231.009375, -------------- SYN_REPORT ------------
Event: time 1619540231.129396, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540231.129396, -------------- SYN_REPORT ------------
Event: time 1619540231.249214, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540231.249214, -------------- SYN_REPORT ------------
Event: time 1619540231.313369, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540231.313369, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 0
Event: time 1619540231.313369, -------------- SYN_REPORT ------------
Event: time 1619540231.593508, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540231.593508, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1619540231.593508, -------------- SYN_REPORT ------------
Event: time 1619540231.649668, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540231.649668, -------------- SYN_REPORT ------------
Event: time 1619540233.001457, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540233.001457, -------------- SYN_REPORT ------------
Event: time 1619540233.041599, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540233.041599, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1619540233.041599, -------------- SYN_REPORT ------------
Event: time 1619540233.145428, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540233.145428, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540233.145428, -------------- SYN_REPORT ------------
Event: time 1619540233.217468, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540233.217468, -------------- SYN_REPORT ------------
Event: time 1619540233.305439, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540233.305439, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 0
Event: time 1619540233.305439, -------------- SYN_REPORT ------------
Event: time 1619540233.321444, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540233.321444, -------------- SYN_REPORT ------------
Event: time 1619540233.417541, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540233.417541, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1619540233.417541, -------------- SYN_REPORT ------------
Event: time 1619540233.505605, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540233.505605, -------------- SYN_REPORT ------------
Event: time 1619540234.849833, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540234.849833, -------------- SYN_REPORT ------------
Event: time 1619540234.897865, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540234.897865, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1619540234.897865, -------------- SYN_REPORT ------------
Event: time 1619540235.041688, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540235.041688, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540235.041688, -------------- SYN_REPORT ------------
Event: time 1619540235.122021, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540235.122021, -------------- SYN_REPORT ------------
Event: time 1619540235.185678, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540235.185678, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 0
Event: time 1619540235.185678, -------------- SYN_REPORT ------------
Event: time 1619540235.209676, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540235.209676, -------------- SYN_REPORT ------------
Event: time 1619540235.305693, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540235.305693, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1619540235.305693, -------------- SYN_REPORT ------------
Event: time 1619540235.385779, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540235.385779, -------------- SYN_REPORT ------------
Event: time 1619540236.762056, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540236.762056, -------------- SYN_REPORT ------------
Event: time 1619540236.810063, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540236.810063, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1619540236.810063, -------------- SYN_REPORT ------------
Event: time 1619540236.945905, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540236.945905, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540236.945905, -------------- SYN_REPORT ------------
Event: time 1619540237.018086, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540237.018086, -------------- SYN_REPORT ------------
Event: time 1619540237.073890, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540237.073890, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 0
Event: time 1619540237.073890, -------------- SYN_REPORT ------------
Event: time 1619540237.097885, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540237.097885, -------------- SYN_REPORT ------------
Event: time 1619540237.225926, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540237.225926, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1619540237.225926, -------------- SYN_REPORT ------------
Event: time 1619540237.297965, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540237.297965, -------------- SYN_REPORT ------------
Event: time 1619540238.578346, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540238.578346, -------------- SYN_REPORT ------------
Event: time 1619540238.618239, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540238.618239, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1619540238.618239, -------------- SYN_REPORT ------------
Event: time 1619540238.746287, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540238.746287, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540238.746287, -------------- SYN_REPORT ------------
Event: time 1619540238.818245, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540238.818245, -------------- SYN_REPORT ------------
Event: time 1619540238.890108, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540238.890108, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 0
Event: time 1619540238.890108, -------------- SYN_REPORT ------------
Event: time 1619540238.914104, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000d
Event: time 1619540238.914104, -------------- SYN_REPORT ------------
Event: time 1619540239.010160, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540239.010160, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 1
Event: time 1619540239.010160, -------------- SYN_REPORT ------------
Event: time 1619540239.098572, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540239.098572, -------------- SYN_REPORT ------------
Event: time 1619540240.538445, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7000f
Event: time 1619540240.538445, -------------- SYN_REPORT ------------
Event: time 1619540240.586457, type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e1
Event: time 1619540240.586457, type 1 (EV_KEY), code 42 (KEY_LEFTSHIFT), value 0
Event: time 1619540240.586457, -------------- SYN_REPORT ------------
Event: time 1619540240.642325, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7002c
Event: time 1619540240.642325, -------------- SYN_REPORT ------------
Event: time 1619540261.933104, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70039
Event: time 1619540261.933104, type 1 (EV_KEY), code 58 (KEY_CAPSLOCK), value 1
Event: time 1619540261.933104, -------------- SYN_REPORT ------------
Event: time 1619540262.189150, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70006
Event: time 1619540262.189150, type 1 (EV_KEY), code 46 (KEY_C), value 1
Event: time 1619540262.189150, -------------- SYN_REPORT ------------

I'm using Colemak keyboard layout, same for ijkl keys.

Hope that helps.

@sezanzeb
Copy link
Owner

sezanzeb commented Apr 27, 2021

can't reproduce on both X11/manjaro/xfce4 and wayland/ubuntu/gnome installations

I'm just pressing Ctrl+Left, Shift+Right (holding) or Ctrl+Left, Right (holding).

you mean ctrl + space + j, shift + space + l, right?

  1. One of the differences to your script is how the UInput is created. Could you please try the trivial-uinput https://github.com/sezanzeb/key-mapper/tree/trivial-uinput branch?

  2. If you don't forward events of code 2 in your own script, does it also lag?

  3. Wayland or X11? Which desktop environment?

@LexRiver
Copy link
Author

you mean ctrl + space + j, shift + space + l, right?

correct

One of the differences to your script is how the UInput is created. Could you please try the trivial-uinput https://github.com/sezanzeb/key-mapper/tree/trivial-uinput branch?

Don't know, same for me. Maybe I'm doing something wrong.

If you don't forward events of code 2 in your own script, does it also lag?

please explain, how not to forward?

I've noticed that when I press "space" key, then all the keyboard input freezes (or caches) for about 1 second and only then appeared on screen. Even when I just typing and using "space" as a usual space between words.
Maybe just some optimizations are needed.

Wayland or X11? Which desktop environment?

Ubuntu 20.10, 64-bit, GNOME 3.38.3, X11, Intel® Core™ i7-3820 CPU @ 3.60GHz × 8, 16GB RAM

@sezanzeb
Copy link
Owner

please explain, how not to forward?

https://github.com/LexRiver/linux-deep-hotkeys/blob/main/linux-deep-hotkeys.py#L150

if event.value == 2:
    continue

Maybe just some optimizations are needed.

My service remained below 1% cpu as far as I remember from yesterday

The event seems to reach your environment and then, for whatever reason, it goes crazy and does nothing for a second.

@LexRiver
Copy link
Author

Well, I've tried your code, with event.value == 2. It works the same fast as before. But now I'm confused how the repeating of keys is still working? -)


I've record for you a video with two evtest windows mapped and forwarded using your key-mapper.

simplescreenrecorder-2021-04-29_14.30.35.mp4

@sezanzeb
Copy link
Owner

sezanzeb commented Apr 29, 2021

The timestamps look correct though. There is a 10 - 30ms gap between each event, even between those that appear after the lag. That means that python-evdev is apparently trying to write the event at the correct time.

  • which kernel version are you using? echo "$(uname -s) $(uname -r)"
  • which python-evdev version key-mapper-control --version
  • and which libevdev versions and whatever apt list --installed | grep evdev

@LexRiver
Copy link
Author

LexRiver commented Apr 29, 2021

lex@pc-lex:~$ echo "$(uname -s) $(uname -r)"
Linux 5.8.0-50-generic
lex@pc-lex:~$ key-mapper-control --version
key-mapper 0.8.1  https://github.com/sezanzeb/key-mapper
python-evdev 1.4.0
lex@pc-lex:~$ apt list --installed | grep evdev

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

libevdev2/groovy-updates,now 1.9.1+dfsg-1ubuntu0.1 amd64 [installed,automatic]
python3-evdev/groovy,now 1.3.0+dfsg-1build1 amd64 [installed,automatic]

@sezanzeb
Copy link
Owner

sezanzeb commented Apr 29, 2021

Thanks. I upgraded to ubuntu 21.04 previously, but I'll try to make my other versions match yours as close as possible later and then try to reproduce it again.

I'll also fork your script and write syn manually instead of forwarding it, maybe that makes the difference.

@sezanzeb sezanzeb mentioned this issue Apr 29, 2021
7 tasks
@sezanzeb
Copy link
Owner

pushed something to my fork of your script: https://github.com/sezanzeb/linux-deep-hotkeys

please try it and report if it also lags now

@LexRiver
Copy link
Author

LexRiver commented May 1, 2021

@sezanzeb I've tried your fork and it's not lagging.
As I mention earlier I've tried to add event.value == 2 and it works without lagging also.

@sezanzeb
Copy link
Owner

sezanzeb commented May 1, 2021

the fork is also injecting its own syn events, not just checking the value of 2

@sezanzeb
Copy link
Owner

sezanzeb commented May 1, 2021

getting my versions to match yours won't work for me after the hirsute upgrade. Too much stuff depending on new versions

kernel 5.8 works for me, no lags. my libevdev2 version is 1.11.0, but I don't know if that is relevant at all. I also never had any lags on groovy

@whot if you have time, do you know what could cause lags like that? Here is a video: #49 (comment) Since the timestamps are correct I guess there must be something beyond key-mapper that has some sort of problem

@LexRiver
Copy link
Author

LexRiver commented May 1, 2021

btw
this config is lagging when I press space:

{
    "mapping": {
        "1,57,1": "set(flag,0).h().ifeq(flag, 0, k(1))"
    }
}

and this is not:

{
    "mapping": {
        "1,57,1": "set(flag,0).h().ifeq(flag, 0, set(flag,1))"
    }
}

also maybe the bug is somehow connected with the following two device parameters:

  • delay before repeat
  • repeat rate

And you are creating two devices and I'm just one, maybe that should be checked also.

@sezanzeb
Copy link
Owner

sezanzeb commented May 1, 2021

Could you please generate some injection debug output? sudo pkill -f key-mapper && sudo key-mapper-service -d, open the gui and apply the preset. Reproduce the lag. Is log written while the input lags (just like in the video when hitting keys that are not mapped)? That would verify that key-mapper basically works the way it is supposed to work from a slightly different perspective.

Your second config is not lagging because the lag must be somehow connected to events that are written to evdev/whatever. Does it also lag if you use a regular simple mapping instead of a macro? You could for example map space to space, which would cause space to be written via the second uinput.

I'll modify your script later to use two uinputs similar to key-mapper.

@LexRiver
Copy link
Author

LexRiver commented May 2, 2021

Could you please generate some injection debug output? sudo pkill -f key-mapper && sudo key-mapper-service -d, open the gui and apply the preset. Reproduce the lag. Is log written while the input lags (just like in the video when hitting keys that are not mapped)? That would verify that key-mapper basically works the way it is supposed to work from a slightly different perspective.

Please watch video

simplescreenrecorder-2021-05-02_18.17.46.mp4

Your second config is not lagging because the lag must be somehow connected to events that are written to evdev/whatever. Does it also lag if you use a regular simple mapping instead of a macro? You could for example map space to space, which would cause space to be written via the second uinput.

Yes, I'm confirming.
bind space to space causing lag.
And seems like it's appearing only on fast keystrokes.
In the following debug I'm typing fast space 3 space 3 space 3 space 3

79045 1210.91 SPAM keycode_mapper.py:444: ((1, 57, 1)) ------------------ maps to 30
79045 1210.99 SPAM keycode_mapper.py:315: ((1, 57, 1), (1, 4, 1)) ------- unknown combination
79045 1210.99 SPAM keycode_mapper.py:449: ((1, 4, 1)) ------------------- forwarding
79045 1211.00 SPAM keycode_mapper.py:377: ((1, 57, 0)) ------------------ releasing 30
79045 1211.10 SPAM keycode_mapper.py:381: ((1, 4, 0)) ------------------- forwarding release
79045 1211.16 SPAM keycode_mapper.py:444: ((1, 57, 1)) ------------------ maps to 30
79045 1211.26 SPAM keycode_mapper.py:315: ((1, 57, 1), (1, 4, 1)) ------- unknown combination
79045 1211.26 SPAM keycode_mapper.py:449: ((1, 4, 1)) ------------------- forwarding
79045 1211.27 SPAM keycode_mapper.py:377: ((1, 57, 0)) ------------------ releasing 30
79045 1211.37 SPAM keycode_mapper.py:381: ((1, 4, 0)) ------------------- forwarding release
79045 1211.41 SPAM keycode_mapper.py:444: ((1, 57, 1)) ------------------ maps to 30
79045 1211.51 SPAM keycode_mapper.py:377: ((1, 57, 0)) ------------------ releasing 30
79045 1211.53 SPAM keycode_mapper.py:449: ((1, 4, 1)) ------------------- forwarding
79045 1211.63 SPAM keycode_mapper.py:381: ((1, 4, 0)) ------------------- forwarding release
79045 1211.67 SPAM keycode_mapper.py:444: ((1, 57, 1)) ------------------ maps to 30
79045 1211.78 SPAM keycode_mapper.py:315: ((1, 57, 1), (1, 4, 1)) ------- unknown combination
79045 1211.78 SPAM keycode_mapper.py:449: ((1, 4, 1)) ------------------- forwarding
79045 1211.79 SPAM keycode_mapper.py:377: ((1, 57, 0)) ------------------ releasing 30
79045 1211.90 SPAM keycode_mapper.py:381: ((1, 4, 0)) ------------------- forwarding release
79045 1211.94 SPAM keycode_mapper.py:444: ((1, 57, 1)) ------------------ maps to 30
79045 1212.03 SPAM keycode_mapper.py:377: ((1, 57, 0)) ------------------ releasing 30
79045 1212.04 SPAM keycode_mapper.py:449: ((1, 4, 1)) ------------------- forwarding
79045 1212.13 SPAM keycode_mapper.py:381: ((1, 4, 0)) ------------------- forwarding release

So bug appears on unknown combination.
If I type slower then no lag.

@whot
Copy link

whot commented May 4, 2021

Well, I've tried your code, with event.value == 2. It works the same fast as before. But now I'm confused how the repeating of keys is still working? -)

X/Wayland do their own key repeat, the kernel key repeats are filtered in libinput and would only affect a VT. Beyond that, no idea sorry, I'm too flat out to look at the key-mapper source and how it works. There's nothing that I'm aware of that handles space in a specific manner, at least not until you get to the toolkits that have to do the actual rendering.

@sezanzeb
Copy link
Owner

sezanzeb commented May 4, 2021

In a nutshell:

  • uinput 1 "forwarded": forwards all events from the grabbed device, except those that are mapped and repeats. capabilities are mostly just copied
  • uinput 2 "mapped": injects custom events, including syns. has exactly those capabilities that it needs for the injection

I guess it's not connected to space but rather to injecting anything at all.

@LexRiver maybe, depending on how much time you have, you can already try to modify your script to work this way? And does it also lag when not using space but some random other key?

I'm too flat out

I understand that, thanks for the info with the repeat events though, very interesting.

@sezanzeb sezanzeb added the environment incompatibility bugs that are impossible for me to track down, key-mapper seems to work correctly label Jul 12, 2021
@sezanzeb sezanzeb changed the title Writing space on release if not part of a triggered combination space on release if not part of combination + input lags Jul 12, 2021
@sezanzeb
Copy link
Owner

sezanzeb commented Sep 22, 2021

Space+J=Left
Space+K=Down
Space+L=Right
Space+I=Up
but
Space=Space

Solution 1

Since april there are set and ifeq, so this would work:

  • space + J -> set(space, 0).h(KEY_LEFT)
  • space -> set(space, 1).h().ifeq(space, 1, h(space))

Solution 2

wait until #183 is released and then do

  • space + J -> KEY_LEFT
  • space -> if_single(h(space), , 0)

@sezanzeb
Copy link
Owner

Solution 2
wait until #183 is released and then do
space + J -> KEY_LEFT
space -> if_single(h(space), , 0)

This has been released a long time ago. I'll close this therefore

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
environment incompatibility bugs that are impossible for me to track down, key-mapper seems to work correctly feature request
Projects
None yet
Development

No branches or pull requests

3 participants