Apple Keyboard (MB110/B). Настраиваем Insert и PrintScreen под Ubuntu.

Сегодняшний пост наверное будет из серии «чем бы дитя не тешилось, лишь бы не покупало девайсы от Apple», да простят меня поклонники и многочисленные фанаты «яблочной» корпорации. Началось все с того что я решил поддаться искушению и приобрести себе клавиатуру Apple MB110/B. Не то чтобы я относил себя к числу фанатов Apple, просто работать с текстами, кодом и т.п. приходится достаточно часто, а следовательно удобство в их наборе играет важную роль.

Те кто так или иначе следил за моим блогом, наверное помнит, что в свое время я купил Defender’овскую клавиатуру с «низкопрофильными» кнопками, подсветкой и прочими радостями жизни, т.к. она по-сути очень походит на клавиатуру моего ноутбука HP, которая меня максимально устраивает. Так вот, спустя несколько месяцев работы на стационарном ПК за Defender’ом я понял что она конечно напоминает ноутбучную, но достаточно отдаленно. Т.е. ход клавиш немного не тот, ощущения от нажатий и т.п. Т.е. аналог конечно, но как-то немного не тот. В поисках максимально удобной для меня клавиатуры я попробовал Apple Wired Keyboard (беспроводные просто не люблю по многим причинам) и как мне показалось — это именно то, что мне подходит. Так что я оформил заказ в DNS — и вот он, час «X» настал. Я забрал заказ, разорвал в клочья Apple’овскую коробку, которую вот в этом видео автор открывает с каким-то непонятным мне благоговейным трепетом и подключил ее к ПК.

Несколько минут знакомства с новым гаджетом подтвердили первоначальный тест — это удобно, но было несколько моментов, которые практически сводили удобство использования клавиатуры на нет, это:

  • По-умолчанию, верхний ряд кнопок F1-F12 работал не как функциональные, а как дополнительные кнопки (!), например, F1 — уменьшал яркость, F2 — увеличивал и т.п. Т.е. это были вовсе не функциональные клавиши, а дополнительные. Теперь представьте, если нам нужно нажать комбинацию кнопок Alt-F1 или Alt-F2, то приходится нажимать целых три кнопки Alt-F1-Fn или Alt-F2-Fn расположенных в разных местах, что чертовские неудобно. Я конечно понимаю, что акробатические этюды на клавиатуре в какой-то степени возможно и востребованы, но я то брал клавиатуру именно для работы, а не для освоения новых трюков. Поэтому F1-F12 мне были нужны как воздух и чтобы они нажимались без дополнительных модификаторов.
  • Отсутствие кнопки Insert … Да, да … на Apple’овской клавиатуре эта кнопка отсутствует в принципе (см. фото в начале статьи), открою секрет, чтобы нажать Insert нужно нажать комбинацию Fn+Enter или переключить дополнительную клавиатуру с помощью NumLock и нажать 0 на дополнительной клавиатуре. Представьте себе каково это вместо Ctrl-Insert или Shift-Insert исполнять этюд в виде Ctrl-Fn-Enter.
  • Отсутствие кнопки Prtsc / SysRq, т.е. банальный PrintScreen знакомый всем Windows пользователям на этом чуде техники отсутствует физически.
  • Ну и последнее … расположение кнопок Ctrl-Alt-Cmd (Cmd на Mac клавиатуре — это Windows-key). Кнопки Ctrl и Cmd большие, а вот Alt находится между ними. Но лично я привык к другому порядку, Ctrl-Win-Alt, при этом Win — маленькая, а Ctrl и Alt должны быть большими. Я привык именно так и переучиваться не собирался. Поэтому в моем понимании нужно было поменять местами Alt и Cmd и тогда все стало бы на свои места.
Казалось бы всего 4 пункта в списке, но для меня они являлись существенными, без них, многие привычные и удобные вещи в работе превращались в 9-й круг ада, т.к. нажимать вместо обычного Ctrl-Ins целых три кнопки я явно не собирался. Да и реакция функциональных кнопок по-умолчанию меня совсем не устраивала.
Первое что я решил сделать — это обратиться к официальному сайту Apple, где я нашел вот это: Изменение назначения функциональных клавиш компьютера Mac. Отлично, всего лишь одна настройка «Использовать функциональные клавиши F1, F2 и др. как стандартные» для первого пункта. Но вот незадача, у нас нет компьютера Mac, у нас даже нет MacOS, а только клавиатура Apple от которой мы хотим добиться такого же поведения. Дальнейшие поиски привели меня к следующему замечательному мануалу, вернее двум:

Автору первого руководства — отдельно спасибо. Честно говоря я не пробовал использовать Apple MB110 в Windows, но почему-то мне кажется что по написанному все пройдет достаточно гладко. Назначение функциональных клавиш в Windows определяется ключом реестра OSXFnBehavior, как видно из статьи. Однако как быть с другими ОС? И в частности моей Ubuntu 16.04? Чтобы найти ответ на этот вопрос пришлось провести еще немного времени с Google и в конечном итоге я наткнулся на мануал:

Который и послужил отправной точкой для решения всех перечисленных задач, правда с небольшими изменениями. Чтобы сделать функциональные клавиши как F1-F12 по-умолчанию в моей Ubuntu 16.04, а также, чтобы поменять местами Alt и Cmd (WinKey) я воспользовался следующими двумя командами:

sudo echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode - включение режима F1-F12 на функциональных кнопках по-умолчанию.
sudo echo 1 | sudo tee /sys/module/hid_apple/parameters/swap_opt_cmd - поменять назначение Alt и Command (Win-Key)

Честно говоря я небольшой специалист в Linux и в Ubuntu в частности, но здесь, как я понял, мы просто определяем параметры модуля hid-apple.ko (/lib/modules/4.4.0-81-generic/kernel/drivers/hid/hid-apple.ko), которые изначально предусмотрены в нем. Желающие могут погуглить про модуль ядра hid-apple и тогда все станет более ясно. После двух этих команд две озвученные проблемы были успешно решены, однако, надо было что-то делать с Insert’ом и PrintScreen’ом. И вот как раз на это у меня ушло несколько часов.

Remap кнопок с помощью xmodmap у меня работал из рук вон плохо. Т.е. если в окне терминала дать команду:


xmodmap -e "keycode 191 = Insert NoSymbol Insert NoSymbol Insert"

То remap работал, но только какое-то ограниченное время и не совсем понятно. Например мы открываем отдельное окно терминала и вводим в нем эту команду, все вроде получается. Т.е. при нажатии F13 в этом окне срабатывает Insert, однако стоит только открыть LibreOffice с помощью ярлыка на рабочем столе — то вот в нем уже почему-то F13 не работает как Insert. Также, соответствующие изменения ~/.Xmodmap с последующей перезагрузкой не привели к желаемому результату. Почитав немного многочисленные сообщения людей, которые пробовали на форуме сделать то же самое, я пришел к выводу что «это не наш метод». Т.к. среди решений было даже что-то вроде создать .desktop файл с запуском xmodmap /home/decker/.Xmodmap и поместить его в Startup Applications … Но и этот метод не у всех работал, как его «дальнейшее развитие», люди делали bash скрипт с чем-то вроде sleep 4 && xmodmap /home/decker/.Xmodmap и все равно, когда-то это работало, а когда-то нет. С этого момента я понял что искать способ remap’а кнопок нужно на более низком уровне.

В одной из статей (было уже достаточно поздно и я читал их по диагонали), я нашел фразу, что чтобы переназначить кнопки или вообще что-то сделать с клавиатурой в Ubuntu нужно представлять каким образом вообще это работает, т.е. представлять как работает «стек драйверов» и каким образом обрабатывается нажатие по цепочке, начиная от нажатия пользователем кнопки на физическом устройстве, обработки этого нажатия драйверами и передачи соответствующего события приложению. Т.к. в Linux’е я не особенно специалист, то приведенная схема (которая по идее должна была открыть глаза на все):


hardware --scancode--> kernel --keycode--> X11 --> keysym --> application

что-то прояснила для меня, но далеко не все (да, да, я не совсем хорошо представляю как работает X11 и что происходит в ядре). Но эта статья дала очередной импульс поискам и я набрел на следующее:

Ключевой точкой был абзац из первой статьи:
Теперь рассказываю как сделал я и как я к этому пришел. Итак, мы решили назначить F13 на Insert, а F15 на PrintScreen. Что же, приступим
1. Ставим утилиту evtest через sudo apt install evtest и запускаем ее, как sudo evtest

2. В появившемся списке выбираем «Apple Inc. Apple Keyboard», у меня это было устройство /dev/input/event17. В выводе утилиты мы увидим нечто вроде:


Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x5ac product 0x250 version 0x111
Input device name: "Apple Inc. Apple Keyboard"

Нажимаем кнопку F13 чтобы определить ее KEYBOARD_KEY_%VALUE%, после нажатия F13 мы увидим:


Event: time 1498176151.012832, -------------- SYN_REPORT ------------
Event: time 1498176154.612842, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70068
Event: time 1498176154.612842, type 1 (EV_KEY), code 183 (KEY_F13), value 1
Отсюда нам нужно запомнить значение value — 70068, это шестнадцатиричное значение. Руководствуясь статьей User XKB Customization проверяем версию udev — udevadm info —ver, в моем случае результатом было 229. Таким образом теперь нам необходимо написать соответствующий файл /etc/udev/hwdb.d/98-apple-keyboard.hwdb . Но как узнать идентификатор для evdev:input? Здесь нам поможет статья How to find the .hwdb header of a general input device? .

3. Выполняем udevadm info /dev/input/event17 и запоминаем ID_VENDOR_ID, в нашем случае это 05ac. Далее делаем find /sys -name *modalias | xargs grep -i 05ac , где 05ac наш vendor_id. Ответом будут множество строк, в том числе и одна, следующего вида:


/sys/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.2/1-11.2:1.0/0003:05AC:0250.0005/input/input20/modalias:input:b0003v05ACp0250e0111... # далее много всего

Здесь нас интересует все что находится после modalias:input до ‘e’, т.е. в нашем случае b0003v05ACp0250 .

4. Создаем файл /etc/udev/hwdb.d/98-apple-keyboard.hwdb от имени root и вписываем туда следующие строки:


evdev:input:b0003v05ACp0250*
 KEYBOARD_KEY_70068=insert      # F13: Insert

Обратите внимание, пробел перед KEYBOARD_KEY важен. После чего делаем:

sudo udevadm hwdb —update и sudo udevadm trigger (убедиться в том что все сработало можно сделав udevadm info /dev/input/event17 | grep KEYB , если в выводе будет что-то вроде KEYBOARD_KEY_70068=insert — значит все Ок).

5. Проверяем визуально, идем в Параметры системы -> Клавиатура -> Ввод текста и нажимаем на иконку клавиатуры под списком раскладок, у нас откроется вот такое окно:

Теперь нажимая F13 мы видим что у нас засчитывается нажатие Insert. Аналогично делаем с F15 -> PrintScreen. Здесь я приведу уже готовый вариант /etc/udev/hwdb.d/98-apple-keyboard.hwdb :


evdev:input:b0003v05ACp0250*
 KEYBOARD_KEY_70068=insert      # F13: Insert
 KEYBOARD_KEY_7006a=sysrq       # F15: PrinScr / SysRq

Вот таким нехитрым образом мы заставили работать функциональные клавиши, а также Insert и PrintScreen на клавиатуре Apple MB110/B под Ubuntu 16.04. При этом мы не использовали «плясок с бубном» вокруг отложенного запуска xmodmap, не разбирались почему не «подцепляется» наш ~/.Xmodmap, а решили проблему «уровнем ниже». И хотя в данном случае до полного понимания принципов работы и назначения udevadm и hwdb нам еще «расти и расти», поставленную задачу успешно удалось решить. Конечно, ее можно было решить и другими путями, например сборкой модифицированного hid-apple.ko (на эту тему также есть соответствующие статьи в интернете, например эта), но фраза «Macbook keyboard is painful» в самом начале как бы намекает 😉 Нет, конечно, можно собрать hid-apple.ko с модифицированным / пропатченным hid-apple.c (кстати есть даже проект на Git’е), однако, для этого нужно еще качать исходники ядра, разбираться как собираются модули, а если у вас Ubuntu на системе с UEFI, как у меня, например, то еще и понимать каким образом заставить грузиться собранный неподписанный hid-apple.ko. Конечно, при наличии времени и должного энтузиазма можно сделать и это, но способ описанный мной чуть проще. Этот пост я уже писал на Apple’овской клавиатуре с работающими так, как мне нужно кнопками.

p.s. Комментарии, предложения, пожелания — приветствуются … и да, Macbook keyboard is painful 😉

Обновлено 24.07.2017 15:56 (MSK)

Для того чтобы сделать предпочтение в работе функциональных клавиш F1-F12 описанное в статье по-умолчанию (т.е. при загрузке системы), а также поменять местами Alt и Cmd (WinKey), достаточно выполнить следующие команды:


echo options hid_apple fnmode=2 | sudo tee -a /etc/modprobe.d/hid_apple.conf
echo options hid_apple swap_opt_cmd=1 | sudo tee -a /etc/modprobe.d/hid_apple.conf
sudo update-initramfs -u -k all
sudo reboot

 

Источник: decker.su