Hacker News new | past | comments | ask | show | jobs | submit login
Understanding Keyboard Events Better (rugu.dev)
68 points by kugurerdem 10 months ago | hide | past | favorite | 24 comments



This is common knowledge already, but the Esc key to change modes was chosen because it made sense when used in ADM-3A[1], which was the terminal used to develop the initial vi version.

Although many people today use Caps Lock for this, the Esc in these terminals was originally in Tab's position.

[1] https://en.wikipedia.org/wiki/ADM-3A


In my vim:

- using Tab while in insert mode leaves the insert mode

- using Tab while typing commands enables the autocomplete

I believe this is a great setup to be closer to the home row when it's not possible to remap Caps to Esc (when alone)+Control (when chorded)


But what do you use to insert tabs then? For me, giving up Caps Lock would be a lot more convenient than giving up Tab, because I almost never use Caps Lock, whereas I use Tab a lot.


Initially, this was my "alternative" setup when I couldn't have Caps lock mapped to both Esc+Control and only doing control, but I've found it easier than using Control-[ for Esc (I never got into this habit) and more reliable that betting wherever I expect Esc to be on the keyboard is where Esc will actually be, or that I'll be on a system with Caps properly remapped.

I need to reliably enter/leave edit mode way more than I need to insert tabs, but I can still insert tabs when needed with Ctrl-q Tab

When do you need to insert tabs in vim?

Personally, I rarely need to insert raw tabs: the only exception may be Makefiles (and for that I have a configuration)


Wouldn’t consider it a real alternative, but you increase/decrease indentation in insert mode with ^t/^d


TECO, though not a visual editor, used the same `[count] command [text ESC]` structure as vi. (It's not a mode switch, it's an argument terminator.)


I didn't know that, that's a really cool information. Thank you! :)


That's one of the reasons why custom keyboards are in demand: you can do all the remapping on firmware level (QMK, etc) and they will work in any application and any OS.


That is very rose-tinted view of the situation. Crucially the keyboard can not bypass the input handling layer of OS, it can only send simple scancodes. That has huge implications on how KB firmware level key remappings work; you can only send scancodes that the OS has in the keymap, and the resulting key press event is still completely dependent on the current keymap. Furthermore, to accomplish more complicated mappings the keyboard will end up sending multiple scancodes, possibly with modifiers, on single keypress, which can make creating application level keybindings problematic.

Ultimately I think the USB HID protocol is bit too crude for these programmable keyboards, because now I need to juggle two sets of keymaps (one on KB side and another on OS side) to accomplish what I want, and it in no way works reliably across computers or OSs. Either that, or OSs should provide better facilities for remapping stuff and handling arbitrary layouts so that keyboards can revert back to being dumb again.


> That is very rose-tinted view of the situation. Crucially the keyboard can not bypass the input handling layer of OS, it can only send simple scancodes

This. Also, even if trying to do without a keyboard (I can't carry one anywhere I go, but I can prepare scripts and environments!), "advanced" scripts can confuse the input handling layer.

> Either that, or OSs should provide better facilities for remapping stuff and handling arbitrary layouts so that keyboards can revert back to being dumb again.

Even if you have better facilities, it's never perfect: I have a Caps to Esc+Control directly on the wayland composer that is quite reliable: Hyprland has advanced options to do key binding and remapping (https://wiki.hyprland.org/Configuring/Binds/) which is a wonderful thing to have when your workflow is keyboard centric.

However, gvncviewer sometimes gets its Caps status confused, and I have to close it and start it again to have access to the unshifted symbols (while it still works for the letter... so it does something like Shift Lock, and while I would love it to work well I can't spend time on just 1 application that refuses to work well with the settings every other application seems to be fine with.


I have been using Vortex POK3R keyboards for a while now and I really enjoy their IJKL arrow keys. I like it so much that it has become a hard requirement for any new keyboard for me. Unfortunately, this rules out most keyboards without flashable firmware support.


Isn't this type of arrow layer also the easiest to rebind in software (using mod+JKL: to not have to move hand off home row) so you could continue to use any hardware keyboard?


Except that firmware is blind to the state of the application (or even which app you're using), which hampers the dream of any OS/any app


When it's an input event in Linux, and you want direct control over what it does, it ultimately ends in writing a daemon with libevdev to get the device event. At least, that is what happened to me last time.


Me too! Following [1].

Maybe worth checking if one is not supported to use libinput instead of processing kernel events directly though. [2]

If someone is interested in the input topic, Peter Hutterer's blog is very nice to read. I also enjoyed his talk about libinput's bus factor [3].

[1] https://who-t.blogspot.com/2013/09/libevdev-handling-input-e...

[2] https://who-t.blogspot.com/2018/07/why-its-not-good-idea-to-...

[3] https://who-t.blogspot.com/2019/10/libinputs-bus-factor-is-1...


These are great references. Read them all briefly, without getting too bogged down in the technical details. As far as I understand it, the libevdev library basically provides one of the lowest levels of interaction with evdev files that comes after reading them yourself, and it is not recommended to read evdev files yourself, as there are many intricacies that can occur.


Here's a simpler approach; not sure it does what you want; mostly just read / decode / display:

https://github.com/rickhull/device_input


I’ve recently spent some time working with terminal emulators in raw mode on macOS. While I chose to handle key events using escape codes, and found it seriously difficult (even gave up) to process the shift modifier key. However, I came across xquartz [1], which seems to do similar things as mentioned in the article. Would detecting shift key state have been trivial using such a library?

[1] https://github.com/XQuartz/XQuartz


Yes but you'd be operating outside the terminal "API" of codes flowing into stdin.


I wrote a more elaborate remapping a while ago and loved having more modifiers that allowed me to have arrow keys and ctrl+shift on my homerow. But the way the keyboard is handled is a bit of a mess in linux, especially now that Wayland is used for some applications. Like my terminal would not use the modified keyboard config.

I also regularly switch between keyboard layouts and when I switch from eg. Chrome to the terminal the keyboard layout changes.


I've just finished writing an essay where I talk about my recent experiments with X and managing keyboard events. If you've had similar experiences or have any thoughts to share that could help clarify things even more, I'd really like to hear your thoughts.


You might find this interesting. I skip the X layer and just access linux device events directly, in Ruby here:

https://github.com/rickhull/device_input


I have just read your README.md file and found your repo interesting indeed. The README is well written. I knew it was possible to read and parse /dev/input/* files, but was hesitant to get into the intricacies you described.

Anyway, great job sir! Now I will read your code out of curiosity :)


Glad to hear it! Don't hesitate to contact me with any questions. You can make issues on the repo for anything that is confusing.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: