ch11ng/xelb

MappingNotify handler slows down typing

fjl opened this issue · 1 comments

fjl commented

Some background: I use xcape to make the space key a control key when typed together with some other key. xcape achieves this feat in the following way:

  • Through xmodmap, space is remapped to an otherwise unused modifier key (Hyper_L in my case),
    and Hyper_L is defined to be a control modifier. An uncommon key is mapped to be space (F12 in my case).
  • xcape monitors key presses through the X record extension and starts a timer whenever Hyper_L is typed. If no other key is pressed shortly after, it sends a fake press and release of F12 (inputting space) through XTestFakeKeyEvent.

Here's the issue: The event handler in commit a8540a5 fires whenever I want to input space, hanging emacs for a short moment while mappings are retrieved synchronously. Somehow, every call to XTestFakeKeyEvent generates multiple MappingNotify events. This is really annoying while typing because it hangs after every word.

You can try to reproduce it by installing xcape and using the files here to set it up.

I'm not that familiar with the X protocol, so not sure what the right solution is. Maybe these events can be ignored in more cases. Maybe getting the updated mappings should be async or delayed or both. I have disabled the handler in my local copy for now and everything still works.

The MappingNotify event is generated whenever the keyboard device is changed. The XTestFakeInput request from the XTEST extension seems to change the keyboard device before and after the call, so two MappingNotify events are generated each time. Without the support of Xkb extension, which does not work on Emacs 24, it's impossible to distinguish between each keyboard device I think. So it's necessary to refresh the keyboard mapping on each MappingNotify event, or the cache can be outdated.

I've added variable xcb:keysyms:auto-update in d06c4c0 to control the auto-update feature. You can disable the feature by setting the variable to nil.