The end of support for xneur has caused me some pain in the last six months. (since the advent of OpenSUSE 15.1 on my desktops: with xneur enabled, windows lose focus and funny flicker in time with keyboard input).
“Ah, damn it, again I started typing in the wrong layout” - in my work it occurs obscenely often. And does not add positive.

At the same time, I (as a design engineer) can formulate quite clearly what I want. And I wanted (first from Punto Switcher, and then, thanks Windows Vista, finally moving to Linux, from xneur) exactly one. Realizing that the gibberish on the screen is in the wrong layout (this usually happens at the end of typing a new word), tap "Pause/Break." And get what you were typing.
At the moment, the product has an optimal (from my point of view) ratio of functionality / complexity. It's time to share.
TL.DR
All sorts of technical details will follow, so first - for the impatient.
The following behavior is currently hardcoded:
- "Pause/Break": pads (Backspace) the last word, switches the layout in the active window (between 0 and 1) and types again.
- "Left Ctrl with nothing": switches the layout in the active window (between 0 and 1).
- "Left Shift without Nothing": turns on layout #0 in the active window.
- “Right Shift without Nothing”: turns on layout #1 in the active window.
From now on, I plan to customize the behavior. Without feedback, it’s not interesting (it suits me anyway). I believe that on Habré there is a sufficient percentage of the audience with similar problems.
Note Because in the current version, the keylogger is attached to "/dev/input/", xswitcher must be run as root:
chown root:root xswitcher
chmod +xs xswitcherNote: the owner of the file with suid must be root, because who is the owner - in that suid and will turn at startup.
Paranoids (I am no exception) can clone from and collect on site. Like that:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### X11 headers for OpenSUSE/deb-based
zypper install libX11-devel libXmu-devel
apt-get install libx11-dev libxmu-dev
cd "x switcher/src/"
go build -o xswitcher -ldflags "-s -w" --tags static_all src/*.go
Add autorun to taste (depending on DE).
Works, "does not ask for porridge" (≈30 CPU seconds per day, ≈12 MB in RSS).
Details
Now - the details.
The entire repository was originally dedicated to my pet project, and I’m too lazy to start another one. So, everything is piled up (just in folders) and covered with AGPL (“patent in reverse”).
The xswitcher code is written in golang, with minimal C inclusions. This approach is supposed to give the least effort (so far). Retaining the ability to connect the missing through cgo.
Comments are laid out in the text, from where they borrowed something and why. Because xneur code "did not inspire" me, took it as a starting point .
Using "/dev/input/" has both its advantages (everything is visible, including the pressed key with auto-repeat) and disadvantages. The cons are:
- Auto-repeat (events with code "2") does not correlate with retry with xx.
- Can't see input through X11 interfaces (this is how VNC works for example).
- Need root.
On the other hand, you can subscribe to X events via "XSelectExtensionEvent()". You can peep at . For go, I didn’t find anything like that, and the draft implementation gave a hundred lines of C-code on the go. For now, put it aside.
The conclusion "back" is made by screwing the virtual keyboard. Thanks to the author of keybd_event, but there is too high-level abstraction and will have to be redone further. For example, the right Win-key selects the 3rd row for me. And only the left Win is translated back.
Known Bugs
- We don't know anything about "composite" input (example: ½). It's not needed right now.
- Incorrectly reproduce the right Win. In my case, it breaks the placement of accents.
- There is no intelligible input parsing. Instead, there are several functions: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Thank you for attentiveness: corrected in the code and here. With a certain probability, you can grab bugs when replacing.
In this place, I do not know "how to" and I will be glad to any suggestions. - (Oh God) concurrent use of channels (keyboardEvents, miceEvents).
Conclusion
The code is the simplest procedural. And stupid like me. So, I console myself with the hope that almost any techie will be able to finish what he wants. And because of this, this product will not perish without support, like most just-for-fun.
Good luck!
Source: habr.com
