6 языков. Как не сойти с ума, переключаясь между раскладками клавиатуры

С изучением языков возникает проблема переключения раскладок клавиатуры. Когда два языка все просто, жамкаешь ALT+SHIFT (или что там у вас) и переключаешься на следующий язык. И ты всегда знаешь на какой именно язык переключился. Когда раскладок становится хотя бы 3 это уже вызывает проблемы. Потому что нажать ALT+SHIFT нужно один или несколько раз и непонятно сколько именно, не посмотрев в угол экрана

Я использую 6 языков, но раскладок у меня 4. Потому что для английского, испанского и немецкого, используется одна English international with AltGR dead keys. Скриншот из Ubuntu. В Windows она тоже есть.

image-loader.svg

По сути это просто английская раскладка, но и использованием правого ALT’а можно печатать дополнительные символы: ñáúéí¡¿ из испанского и äöüß из немецкого.

image-loader.svg

Таким образом вместо 6 раскладок у меня 4, но это все равно много.

Я долго мучался. Одно время вешал разные раскладки на разные комбинации клавиш например ALT+1 — английкский, ALT+2 — русский, ALT + 3 польский и так далее. Но это было неудобно по двум причинам. Во-первых, эти сочетания клавиш уже задействованы в IDE, а во-второых, ALT+SHIFT как-то поудобнее чем ALT + 1. Поэтому я отказался от этого и продолжил мучаться с ALT+SHIFT, никогда не зная, на какой следующий язык я переключусь.

Потом я стал думать в направлении того, как разделить сочетания клавиш для основных и дополнительных языков. Т.е. например между en / ru я переключаюсь и использованием левых ALT+SHIFT, а между pl / uk с помощью правых ALT+SHIFT.

Возможно существуют какие-то инструменты, которые так умеют. Но я ничего подобного не нашел. Написать самому, казалось достаточно просто, берем готовую библиотеку для хоткеев, и потом остается отправить какие-то команды операционной системе на переключение раскладки.

Я использую Ubuntu, поэтому мое решение работает под этой ОС. Сначала я поискал библиотеки для перехвата горячих клавиш.

  1. https://github.com/boppreh/keyboard (python) — не подошла, т.к. требует root.

  2. https://github.com/timeyyy/system_hotkey (python) — умеет ловить хоткеи, но кроме ALT/CTRL/SHIFT в сочетании всегда должен быть какой-то символ например CTRL+A. Мне хотелось именно привычного ALT+SHIFT.

  3. https://github.com/jamesbirtles/hotkey-rs (rust) — такая же проблема, как у предыдущей плюс на одном компе она работала, а на втором нет.

  4. https://github.com/golang-design/hotkey (go) — судя по документации у нее такая же проблема как у предыдущих двух.

  5. https://crates.io/crates/inputbot (rust) — требует root.

  6. https://github.com/moses-palmer/pynput (python) — сначала я подумал, что наконец то нашел, то что нужно. Но с ней был ряд проблем. Во-первых, не работает правый ALT (есть даже issue на эту тему). Но эту проблему удалось победить. Но с левым альтом было еще хуже. В зависимости от того нажат сначала ALT или SHIFT выдаются разные коды (назовем их ALT и WTF_ALT), поэтому сочетания клавиш работает через раз. Я частично решил эту проблему, забиндив 3 комбинации клавиш ALT+SHIFT, WTF_ALT+SHIFT и ALT+WTF_ALT+SHIFT. Но там возникли дополнительные проблемы — для WTF_ALT срабатывает событие PRESSED, но нет события RELEASED. Это тоже можно было победить. Но мне надоело городить костыли вокруг этой библиотеки и я пошел искать дальше.

А дальше никакой волшебной библиотеки я не нашел, зато нашел пример кода на stackoverflow. Я конечно уже видел его раньше, но после всех мучений с библиотеками решил попробовать его. Там нет готовых функций для отслеживания комбинаций клавиш, зато можно вручную отследить события PRESSSED и RELEASED. Далее нужно уже самостоятельно куда-то складывать нажатые клавиши, удалять их и сравнивать с образцами.

Еще оставалось выяснить как получить список языков и как их переключать. Ответ нашелся все там же)

Получить текущий индекс языка:

gdbus call --session \
--dest org.gnome.Shell \
--object-path /org/gnome/Shell \
--method org.gnome.Shell.Eval \
"imports.ui.status.keyboard.getInputSourceManager().currentSource.index"

Активировать язык по индексу:

gdbus call --session \
--dest org.gnome.Shell  \
--object-path /org/gnome/Shell  \
--method org.gnome.Shell.Eval \
"imports.ui.status.keyboard.getInputSourceManager().inputSources[0].activate()"

Этого хватило, чтобы написать прототип, захардкодив языки в переменных и вызывая эти команды через subprocess:

cmd = "gdbus call --session --dest ....
subprocess.call(cmd, shell=True).

Далее нужно было немного обработать напильником.

Еще нужно поместить скрипт в автозагрузку, можно сделать это через GUI или создав файлик нужного формата в директорию ~/.config/autostart/

image-loader.svg

В итоге получился небольшой проект https://github.com/un1t/gnome-keyboard-layout-switching, который можно скачать и установить себе.

© Habrahabr.ru