Нов аналог на Punto Switcher за linux: xswitcher

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

«А, по дяволите, отново започнах да пиша в грешната разкладка» — в работата ми се среща твърде често. И не добавя позитивизъм.

Нов аналог на Punto Switcher за linux: xswitcher
В същото време, аз (като инженер-конструктор) мога достатъчно ясно да формулирам какво искам. А исках (първоначално от Punto Switcher, а след това, благодаря на Windows Vista, окончателно преминавайки на Linux, от xneur) точно едно. Осъзнавайки, че на екрана има неразбория в грешната разкладка (това обикновено се случва в края на написването на нова дума), да натисна «Pause/Break». И да получа това, което написах.

В момента продуктът има оптимално (от гледна точка на мен) съотношение функционалност/сложност. Време е да споделя.

TL.DR

Нататък ще следват всякакви технически подробности, затова първо — линк «за проба» за нетърпеливите.

В момента е хардуерно зададено следното поведение:

  • «Pause/Break»: изтрива (Backspace) последната дума, превключва разкладката в активния прозорец (между 0 и 1) и набира отново.
  • «Ляв Ctrl без нищо»: превключва разкладката в активния прозорец (между 0 и 1).
  • «Ляв Shift без нищо»: включва в активния прозорец разкладка №0.
  • «Десен Shift без нищо»: включва в активния прозорец разкладка №1.

От този момент планирам да персонализирам поведението. Без обратна връзка — не е интересно (мен и така ме устройва). Предполагам, че на Хабра ще се намери достатъчен процент от аудитория с аналогични проблеми.

N.B. Тъй като в текущата версия кейлоггерът се прикрепя към "dev/input/", xswitcher трябва да се стартира с администраторски права:

chown root:root xswitcher
chmod +xs xswitcher

Обърнете внимание: собственикът на файла с suid трябва да бъде root, тъй като какъвто е собственикът — такъв ще направи suid при стартиране.

Параноиците (аз не съм изключение) могат да клонят от GIT и да компилират на място. Примерно така:

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 МБ в RSS).

Подробности

Сега — подробности.

Целият репозиторий първоначално беше посветен на моят проект, а да започна друг — поне сега ми е мързяло. Така че всичко е струпано в купчина (просто по папки) и покрито с AGPL («обратен патент»).

Кодът на xswitcher е написан на golang, с минимални вкрапвания на C. Предполага се, че подходът ще доведе до най-малък разход на труд (засега е така). Оставя се възможност за включване на недостигащото чрез cgo.

В текста са разположени коментари, откъде съм заимствал какво и защо. Тъй като кодът xneur не ме вдъхнови, взех за отправна точка loloswitcher.

Използването на "\/dev\/input\/" има както плюсове (всичко се вижда, включително натиснат клавиш с автоповтор), така и минуси. Минусите са следните:

  • Автоповторът (събитията с код «2») не корелира с повторите в X.
  • Не се вижда входът през интерфейсите X11 (например VNC работи по този начин).
  • Нужен е root.

От друга страна, можем да се абонираме за събития X чрез "XSelectExtensionEvent()". Може да се погледне в кода xinput. За go не намерих нещо подобно, а черновата реализация извади от раз сто реда C-код. Засега го отложих настрана.

Изходът "обратно" за момента е реализиран чрез добавяне на виртуална клавиатура. Благодаря на автора на keybd_event, но там е прекалено високоефективна абстракция и след това ще трябва да се преизгради. Например, при мен дясната клавиша Win от третия ред избира. А обратно се транслира само лявата Win.

Известни грешки

  • Нищо не знаем за "композитния" вход (пример: ½). В момента не е необходимо.
  • Неправилно възпроизвеждане на дясната Win. В моя случай разваля разположението на акцентите.
  • Няма ясен анализ на входа. Вместо това — няколко функции: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Благодаря nsmcan за вниманието: поправих в кода и тук. С определена вероятност могат да се вземат бъгове при заместване.
    На това място не знам "как трябва" и ще се радвам на всякакви предложения.
  • (О ужас) конкурентно използване на канали (keyboardEvents, miceEvents).

Заключение

Кодът — най-прост процедурен. И глупав като мен. Така че, тешу се с надеждата, че желаното ще може да напише практически всеки техник. И това изделие благодарение на това няма да изчезне без подкрепа, подобно на повечето just-for-fun.

Успех!

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster