5

How can I build a component that sits between the keyboard and applications that captures all key presses and emits it's own key press signals. The emitted signals won't necessarily be 1-to-1 with those captured. Ultimately, I'm attempting to create an input method similar to ibus (I'd also appreciate information on how ibus works technically).

After reading this question, I think the appropriate place to capture would be after keycodes or keysymbols are generated. I also understand X allows a client to grab all keyboard events which sounds relevant to what I'm trying to do.

1

1 Answer 1

5

There are basically two ways:

1) On the kernel level, find the /dev/input device that produces your keypresses, open it and do a "grab"-ioctl (same as evtest --grab does). That will cause this input device to send the key events exclusively to your application. Then use /dev/uinput to create your own input device from your application, where you can send key events out. X should connect to that device automatically.

2) On the X level, intercept keypress events just like the window manager does, and send out your own events with XSendEvent instead. I am not sure a grab would be the best way to do it; grabs are intended for a situation when some application temporarily wants to intercept all events during a specific interaction.

I have no idea what ibus does (maybe even a third method), I haven't looked at it in detail.

Edit

Had to look this up, because it's too long that I read about all the X details.

There are two basic grab functions: XGrabKeyboard, which generates FocusIn and FocusOut events, and takes complete control of the keyboard (active grab). This is the function I meant when talking about X grabs above, and this is the function that should only be active temporarily.

There is also XGrabKey, which registers a passive grab for specific keycodes. Looking very quickly at the source code of the window manager fvwm, this seems to be what the window manager uses.

The details of this are complicated enough that you probably want to dig up some documentation about how to program a window manager (or read source code, maybe even ibus source code).

2
  • Thanks! For the second approach, how do you intercept events without grabbing? The closest example I can find is stackoverflow.com/a/11322335/1973358 but that seems to be grabbing the keyboard.
    – Elfalem
    Commented Oct 28, 2017 at 1:03
  • Thanks again. Reading about XGrabKey, it seems to be what one uses to listen for a specific shortcut or hotkey. However, if my understanding is correct, for an input method, one would want to actively grab the keyboard for an extended period since the program would act on all of the user's key presses.
    – Elfalem
    Commented Oct 31, 2017 at 2:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .