«А, блин, опять не в той раскладке начал набирать» — в моей работе встречается до неприличия часто. И позитива не добавляет.
В то же время, я (как инженер-конструктор) могу достаточно ясно сформулировать чего хочу. А хотел я (сначала от 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 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.
Удачи!
mtforlj
Вот бы еще кто Punto Switch допилил, чтобы при использовании Caps Lock в качестве
кнопки-переключалки он в случайный момент времени не вспоминал о исходном ее назначении, и не отказывался переключать раскладку. Регистр меняет, раскладку нет.
Приходится выгружать :(
Или я что-то не так делаю?
Andriy1218
У меня такая ситуация наблюдается с рабочим ноутбуком, где стоят дефолтные настройки винды и где работают всякие McAfee. А вот на личном компьютере где стоит Windows 10 ltsc с «правильными настройками» никаких проблем с Punto Switcher не наблюдал ни разу.
Может тут конечно и виноват Punto Switcher, но это проблема видимо проявляется только с определенными настройками системы.
mtforlj
У меня и W7 и Win10 (был, пока не достал окончательно). Возможно, что и с параметрами настройки систем что-то, но уж очень они «по умолчанию» в моем случае :)
PS. А вот в OpenSuse (любимый дистр!:) никаких проблем «из коробки» с переключалками не наблюдалось уже лет 15. Но мне и автозамена без надобности, ради которой аффтар все и затеял.
kaverdo
Попробуйте отключить в настройках «Исправлять две заглавные буквы в начале слова» и «Исправлять случайное нажатие Caps Lock», а в винде настроить отключение режима Caps Lock клавишей Shift. Это в комбинации решило похожую проблему у меня: при полностью отключенной клавише Caps Lock, сам Caps Lock иногда включается, а выключить нельзя (клавиша же отключена).
mtforlj
Ооо, спасибо большое, попробую!
andersong
Ещё в Пунто при назначении Капса на переключение языка перестает работать индикатор на клаве. Я писал в ТП Яндекса, они ответили, что если Капс переназначен, то и индикатор не работает. Было давненько, может и исправили.
pav7ka
Выявил, что у меня такое наблюдается только с программой keepassxc, если встать на поле ввода пароля для разблокировки БД и переключить раскладку caps`ом. punto на рабочем АРМе держу только из-за того переключения, на домашней машинке под linux привык к такому переключению.
Посчитал, что «враждуют» между собой hook`и keepassxc`а punto`а.
mtforlj
Нет, не оно. Я keepass не юзаю.
Я тоже сначала думал, что это Remote Desktop Manager виновен, но потом эффект появился на той машине, где его сроду не было. Так что это что-то «тама унутре» неучтено.
Коллега сверху по треду предложил некое сильное шаманство, вот, тестирую :)