Introducing Jemclicks - A Linux mouse emulator

Photo by Muha Ajjan on Unsplash

Introducing Jemclicks - A Linux mouse emulator

And a humble attempt at Rust programming and ergonomics

What is Jemclicks?

Jemclicks is an open-source mouse emulator for Linux, built with Rust. You can use it to control your mouse pointer with any keyboard.

Why?

Earlier this year, I got myself a new mechanical keyboard. This keyboard is a wide-version split keyboard, with a cable long enough to fit a laptop in between or just have a usable working space.

There is a slightly bigger penalty for not touch typing properly on a split keyboard, though. This shouldn't be a surprise as in a regular keyboard you only have one place to look at, versus two on a split one. A small glance down becomes a little head dance from looking for the right letter between the two panels.

So, having a brand new keyboard I still didn't know the key positions from memory, I dreaded every time I had to move my hands off it. And even though with practice finding my way back to the right place got easier as my muscle memory improved, I still wished I didn't have to move my hands at all and could use my fancy new keyboard as a pointer device.

Was this enough of a reason, though?

As is usual for many others, I forgot this idea for a while. I didn't have the time or motivation to invest in building a mouse emulator and didn't even know where to start.

But then something happened. One day, watching a Twitch streamer live programming osu!, I observed what seemed to be the absolute pinnacle of keyboard productivity. Of productivity in general, to be fair.

Peppy moved around faster than thought. He navigated between browser tabs, vim buffers, replying to and closing Github issues, and even interacting with osu! itself faster than anything I’ve seen. I tried to dissect and understand how he achieved such control of his environment. He streams with a hand cam but this only confused me further: the hands barely moved, except for the occasional stretch or a little vibing to the music.

Even more, between his skillful use of browser shortcuts (I could catch that he uses the very nice Vimium extension) and OS navigation, the mouse pointer came to life for sometimes less than a second. Usually, the pointer moved and clicked something on the screen before I could even look back at the hand cam. I wasn’t even sure he was using his hands to control it.

But his Twitch profile confirmed that he was using the keyboard to control his mouse. He uses a custom QMK firmware with mouse emulation. QMK is used in many mechanical keyboards in the market but, unfortunately, not in mine, and certainly not in my laptop's keyboard.

On to building a new mouse emulator

I decided to achieve that same kind of control. Not having to move the hands off the keyboard, not even for mousing around, seemed like a necessary step to achieve that kind of productivity. So I got to work.

Granted, nothing can replicate the preciseness and speed of a real mouse or trackball. So do not expect to be able to play an FPS with an emulated mouse.

Still, Jemclicks is a much more fluid experience than most other “up-down-left-right” emulators. Its movement speed eases in and out to provide a more natural experience. This also enables minor adjustments to the pointer position, as well as longer motions across the screen.

Pro tip: Long motions are a good indicator that there’s an app shortcut to be used instead. I noticed that a significant part of my mouse usage was spent closing or switching browser tabs. Now, I mostly use the keyboard to control tabs, taking me a tiny bit closer to Peppy productivity levels.

By default, the keys are not the regular arrow keys but letter keys specifically chosen for their placement on the center of most keyboards - In fact, the original letter choice maps almost completely to the library name ;) - This is to reduce the need to take the hands off the keyboard, building muscle memory instead of wasting time reaching for the mouse or looking for the right keys.

Multiple keys/directions can also be used together, and directions ease in/out individually. This is important because I wanted to avoid sharp movements and abrupt accelerations. The most basic emulators only give you four directions to move (eight, at best, if they permit diagonal movements) and their speed is linear and jumpy. Being able to track and predict the pointer moves is essential for precise control, so I built Jemclicks with this goal in mind.

Peek 2022-11-12 21-01.gif

Is it complete?

Certainly not.

I mentioned I used Rust to build this library. But I'm not a seasoned Rust developer by any means. In fact, this is the first Rust program I've ever written. I've long wanted to learn Rust, and I finally found both the time and an interesting enough problem to learn the language. Still, with my minimal chops, there are plenty of features that didn't make it to the alpha release, but I would love to address them in the future:

  • Customizing the mouse behavior from a simple configuration file.
  • More ways of toggling in/out of mouse mode. Eg. keyboard shortcuts. A special press-to-mouse button was the original implementation, but it was too unreliable for release.
  • Adding scroll movements (!).
  • Deamonize the process.
  • Adding a test suite, and taking care of bugs and reliability issues.

If you are a Rust developer or are also learning the language and would like to contribute to a brand new project, head over to the project's Github site. Every little bit of feedback is appreciated. You can leave me any suggestions and ideas or probably direct me to the right language tools so I can build the missing features.

Still, I'm currently using Jemclicks as my only mouse, with its quirks and missing features, and the experience is more than adequate for everyday use; I'm hoping it will only get better over time.

Trackball in a corner

My Kengsinton Expert wireless trackball looking all sad in a corner.

Where to start?

Head to the project's Github page for download and installation instructions. Also, reach out to me at the Rust Lang slack or at Twitter @dceluis for help or questions.

Hope you find this little library useful.

Happy hacking!