Прекратяването на поддръжката на xneur ми създаде определени затруднения през последните шест месеца. (с появата на OpenSUSE 15.1 на моите настолни компютри: с включен xneur прозорците губят фокус и забавно мигат в ритъм с въвеждането от клавиатурата).
„Ах, по дяволите, отново започнах да набира на грешната подредба“ — в работата ми срещам това прекалено често. И не добавя позитивизъм.

В същото време, аз (като инженер-конструктор) мога достатъчно ясно да формулирам какво искам. И исках (първоначално от Punto Switcher, а след това, благодаря на Windows Vista, окончателно преминал на Linux, от xneur) точно едно. Разбирайки, че на екрана е пълна бъркотия на грешната подредба (такова се случва обикновено в края на въвеждането на нова дума), да натисна „Pause/Break“. И да получа това, което печатах.
В момента продуктът има оптимално (от моя гледна точка) съотношение функционалност/сложност. Време е да споделя.
TL.DR
Далече оттук ще последват всякакви технически подробности, така че първо — за нетърпеливите.
В момента е закодирано следното поведение:
- „Pause/Break“: изтрива (Backspace) последната дума, превключва подредбата в активния прозорец (между 0 и 1) и набира отново.
- „Леви Ctrl без нищо“: превключва подредбата в активния прозорец (между 0 и 1).
- „Леви Shift без нищо“: включва в активния прозорец подредба №0.
- „Десен Shift без нищо“: включва в активния прозорец подредба №1.
От този момент планирам да персонализирам поведението. Без обратна връзка — не е интересно (мене и така ме устройва). Предполагам, на Хабра ще има достатъчно процент от аудиторията с подобни проблеми.
Забележка. Т.к. в текущата версия кейлоггерът се прикрепя към "/dev/input/", xswitcher трябва да се стартира с рутови права:
chown root:root xswitcher
chmod +xs xswitcherОбърнете внимание: собственикът на файла с suid трябва да бъде root, т.к. който е собственик — в него suid ще се активира при стартиране.
Параноиците (аз не правя изключение) могат да клонят от и да съберат на място. Приблизително така:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### X11 заглавия за OpenSUSE/deb-базирани системи
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
Автозареждане добавете по вкус (в зависимост от DE).
Работи, „не иска много“ (≈30 секунди CPU на ден, ≈12 MB в RSS).
Подробности
Сега — подробности.
Целият репозиторий първоначално е посветен на моя личен проект, а да създам друг — все още ми е твърде мързеливо. Така че всичко е събрано накуп (просто по папки) и покрито с AGPL («обратен патент»).
Кодът на xswitcher е написан на golang, с минимални вкрапвания от C. Предполага се, че този подход ще доведе до най-ниски трудови разходи (досега е така). Запазвайки възможността за свързване на недостигатата част чрез cgo.
В текста са разложени коментари, откъде какво е взето и защо. Тъй като кодът на xneur не ме вдъхнови, взех за отправна точка .
Използването на "\/dev\/input\/" има както своите плюсове (всичко е видимо, включително натиснат клавиш с авто повтаряне), така и минуси. Минусите са:
- Авто повтарянето (събития с код «2») не координира с повторението от X.
- Не е видимо въвеждането през интерфейсите X11 (както например работи VNC).
- Нужен е рут.
От друга страна, можете да се абонирате за събития X чрез «XSelectExtensionEvent()». Можете да погледнете в . За go не намерих нещо подобно, а черновата реализация даде веднага сто реда C-код. Досега го отложих настрана.
Изходът «назад» в момента е направен чрез прикачване на виртуална клавиатура. Благодаря на автора на keybd_event, но там е твърде високо ниво на абстракция и после ще трябва да се преработи. При мен, например, десният Win-клавиш изкарва третия ред. А обратно се прехвърля само левият Win.
Известни грешки
- Нямаме информация за «композитното» въвеждане (пример: ½). В момента не е необходимо.
- Неправилно възпроизвеждам десния Win. В моя случай нарушава разположението на акцентите.
- Няма ясна разбивка на входа. Вместо това — няколко функции: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Благодаря за вниманието: поправих в кода и тук. С определена вероятност може да се проявят грешки при замяната.
На това място не знам «как трябва» и ще се радвам на всякакви предложения. - (О ужас) конкурентно използване на каналите (keyboardEvents, miceEvents).
Заключение
Кодът — най-простият процедурен. И глупав като мен. Така че, успокоявам се с надеждата, че желаното ще може да бъде дописано практически от всеки технар. И това изделие благодарение на това няма да изчезне без поддръжка, както повечето just-for-fun.
Успех!
Източник: habr.com
