Новий аналог 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.

З цього моменту я планую кастомізувати поведінку. Без зворотного зв'язку – не цікаво (мене і так влаштовує). Вважаю, на Хабрі знайдеться достатній відсоток аудиторії з аналогічними проблемами.

NB Т.к. у поточній версії кейлоггер прикручується до "/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 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

Автозапуск додавати до смаку (залежно від DE).

Працює, «каші не вимагає» (30 секунд CPU на добу, 12 МБ в RSS).

подробиці

Тепер подробиці.

Весь репозиторій спочатку був присвячений моєму пет-проекту, а інший заводити — поки що ліньки. Отже, все звалено в купу (просто за папками) та накрито AGPL (патент навпаки).

Код xswitcher написаний на golang, з мінімальними вкрапленнями C. Передбачається, що такий підхід дасть найменші витрати (поки що так і є). Зберігаючи можливість підключати недостатнє за допомогою cgo.

За текстом розкладено коментарі, звідки запозичив і навіщо. Т.к. код xneur мене «не надихнув», за відправну точку взяв loloswitcher.

Використання /dev/input/ має як свої плюси (все видно в т.ч. клавішу з автоповтором), так і мінуси. Мінуси такі:

  • Автоповтор (події з кодом «2») не корелює з повтором з іксами.
  • Не видно введення через інтерфейси X11 (наприклад VNC працює).
  • Потрібний рут.

З іншого боку, можна підписуватись на події X через «XSelectExtensionEvent()». Піддивитися можна в коді xinput. Для go нічого подібного не знайшов, а чорнова реалізація дала з ходу сотню рядків C-коду. Поки відклав убік.

Висновок «назад» поки що зроблено через прикручування віртуальної клавіатури. Дякую автору keybd_event, але там надто високорівнева абстракція і далі доведеться переробляти. У мене, наприклад, права Win-клавіша 3 ряд вибирає. А назад транслюється лише ліва Win.

Відомі помилки

  • Нічого не знаємо про «композитне» введення (приклад: ½). Прямо зараз воно не потрібне.
  • Невірно відтворюємо праву Win. У моєму випадку ламає розстановку акцентів.
  • Немає чіткого аналізу введення. Натомість кілька функцій: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Дякуємо nsmcan за уважність: виправив у коді і тут. З певною ймовірністю можна відхопити баги під час заміни.
    У цьому місці я не знаю «як треба» і буду радий будь-яким пропозиціям.
  • (О жах) Конкурентне використання каналів (keyboardEvents, miceEvents).

Висновок

Код – найпростіший процедурний. І тупий як я. Так що тішу себе надією, що дописати бажане зможе практично будь-який технар. І цей виріб завдяки цьому не згине без підтримки подібно до більшості just-for-fun.

Удачи!

Джерело: habr.com

Додати коментар або відгук