CLI application similar to Karabiner (Mac) for Linux in Rust?


TLDR; How would one implement a CLI application similar to Karabiner-Elements (Mac) for Linux in Rust?

I just recently moved to Linux from Mac and the one thing I miss the most is the application Karabiner. To easily, and quickly, change between key maps. I constantly switching between English and Swedish keyboard setup, as well as a "modified" Swedish setup I call "code", which I use for programming.
Ive so far used setxkbmap to switch around keys a bit, but it is a bit clunky.

I also recently started learning Rust and want to start building all my small apps in Rust for a while to get used to the language.

What I want to do
I want to write a CLI application that lets you setup profiles of custom key maps and to easily switch between them.
A key map can either be a pre-defined map such as "English" or "Nordic", but it can also be custom. So the application needs to be able to capture and setup custom mappings (for example the very common remapping of Caps Lock to Escape).

How would you implement something like that in Rust?
Can the keyboard layout be set directly, or would it be better to build a wrapper around something like setxkbmap? Is it a bad idea altogether?

Depending on your WM/DE you can use keyboard shortcuts to switch between a predefined set of keyboardlayouts, also as you said there is already setxkbmap which does switch between layouts, I'm not sure what functionality you need beyond that...

Only thing I can think of where per window layout, which my WM doesn't support, but Unity and Gnome do AFAIK, and I'm pretty sure KDE does as well...

I can't find how to setup custom keyboard layouts in KDE, and I find setxkbmap to not be as user friendly as I would like.

So, let's say I wanted to re-implement the functionality myself. What would I need to learn? Would it be possible in Rust?

I'd probably just wrap setxkbmap. If you want to extend, I'd check if there is some API exposed by X to change the keyboard layout. (Or Wayland, depending on what you use)

Do you know how would you implement this in another programming language?

For bigger problems the answer for Rust usually is "the same way as you'd do it in C", possibly with an extra step of wrapping C APIs into something safer, if there isn't a crate for it already (like nix or library-specific crates)

1 Like