Caps Lock sucks on MacOS
wardxela
Введение
Мне нравится оптимизировать повторяющиеся действия. Думаю, все программисты разделяют это чувство. Одним из таких действий для меня является переключение языковой раскладки на клавиатуре.
Когда-то давно, еще когда я пользовался Windows, я узнал из видео Вадима Макеева, что на MacOS существует возможность для переключения языка с помощью Caps Lock. Тогда, конечно, я побежал искать аналогичную возможность в Windows и быстро успокоился, так как ее там нет 😁*. Но да и ладно, эта статья не про Windows.
Когда я впервые попробовал Linux в качестве операционной системы, меня поразило изобилие возможностей для настройки поведения клавиш. Можно переопределить и переназначить любую клавишу, задать свою скорость повторения символов и даже полностью убрать задержку зажатия клавиш. Разумеется, что настроить Caps Lock там не составило никакого труда.
И наконец, когда в моих руках впервые оказался MacBook, почти первое, что я сделал, это переназначил Caps Lock для переключения языка. Сделать это даже проще, чем в Linux — достаточно зайти в настройки клавиатуры и активировать единственный чекбокс:

Но эта статья не назвалась бы Caps Lock sucks on MacOS, если бы все работало как должно быть.
Проблема
Оказывается, клавиша Caps Lock на MacOS менее чувствительная, чем другие кнопки. То есть некоторые нажатия MacOS просто проигнорирует, посчитав их случайными и ненамеренными. Во время работы мне приходится очень часто переключать раскладку, и когда очередное мое действие игнорируется операционной системой, это начинает чертовски раздражать.
Приступив к поиску в интернете на тему Caps Lock, я быстро обнаружил, что я не один, кто столкнулся с этой проблемой.
Вот, например, вопрос на Apple StackExchange. А вот аналогичный на Reddit. Там, люди предлагают разные решения. Кто-то создает целое приложение, чтобы исправить эту проблему. Кто-то заявляет, что проблему можно решить одной командой в консоли (у меня не работает):
hidutil property --set '{"CapsLockDelayOverride":0}'
Но по настоящему решить проблему можно только одним способом — сделать так, чтобы клавиша Caps Lock вообще не была связана с изначальным поведением. То есть переназначить ее на несуществующую клавишу (например, F13), а затем назначить клавише F13 задачу переключать язык.
Karabiner-Elements
Самым простым способом осуществить задуманное можно с помощью сторонней программы — Karabiner-Elements.
После установки приложения переходим в настройки и переназначаем клавишу Caps Lock на F13

Далее уже в настройках Mac назначаем F13 в качестве клавиши для переключения языка. (Когда вы нажмете на Caps Lock, напечатается F13)

Но это решение далеко до идеала, так как требует установки лишнего, громоздкого приложения, требующего множество Accessibility привилегий.
По этой причине я занялся поиском нативного способа для решения этой проблемы.
Без сторонних приложений
На Хабре уже есть статья на данную тему — Переназначение клавиш в macOS без стороннего софта и консоль как в Quake, поэтому от себя я добавлю полезные ссылки и как оформить решение на Nix.
В основе всего решения лежит следующая команда:
hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x700000068}]}'
Попробуем разобраться, что она делает.
- Мы вызываем системную команду
hidutilи устанавливаем значение для ключаUserKeyMapping, отвечающего за переопределение клавиш. - В качестве значения мы передаем список, в котором каждый элемент отвечает за одну пару клавиш (В нашем случае Caps Lock и F13)
{
// Исходная клавиша (Caps Lock)
"HIDKeyboardModifierMappingSrc": 0x700000039,
// Финальная клавиша (F13)
"HIDKeyboardModifierMappingDst": 0x700000068
}
Но что из себя представляют эти 0x700000039 и 0x700000068 и откуда они берутся? Это идентификаторы клавиш, представленные в формате HEX. Полный список можно посмотреть здесь.
После запуска команды, Caps Lock начнет работать как F13, поэтому можно назначить этой клавише задачу переключать язык и все готово... Почти.
Осталась одна проблема — команда hidutil не сохраняет настройки после перезагрузки системы. Для этого можно настроить LaunchAgent. В Nix это делается очень легко:
launchd.user.agents = {
keyremap = {
serviceConfig = {
Label = "com.user.keyremap";
ProgramArguments = [
"/usr/bin/hidutil"
"property"
"--set"
''{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x700000068}]}''
];
RunAtLoad = true;
KeepAlive = false;
};
};
};
И дополнительно, можно назначить клавише F13 переключение языка:
system.defaults.CustomUserPreferences = {
"com.apple.symbolichotkeys" = {
AppleSymbolicHotKeys = {
# Select next source in input menu
"60" = {
enabled = true;
value = {
parameters = [
65535
105
0
];
type = "standard";
};
};
};
};
};
65535 105 0 — это код клавиши F13. Подробнее можно почитать здесь.
Полный код настройки моего окружения MacOS с помощью Nix можно найти у меня на GitHub.
Заключение
Забавно видеть, как в начале статьи я заявляю, что на MacOS настроить Caps Lock проще всего, а на деле все оказывается с точностью наоборот. Именно этим и отличаются такие "user-friendly" ОС как MacOS и Windows. Пытаясь угодить всем, они не удовлетворяют запросы вообще никого. Эти системы позволяют с легкостью решать легкие проблемы и с большим трудом справляются (или вовсе не справляются) с задачами посложнее, в то время как Linux дает пользователю все необходимые возможности, чтобы с одинаково умеренными усилиями решать как легкие, так и очень трудные задачи.
Всего вам продуктивного.
Примечание: на самом деле в Windows можно настроить Caps Lock для переключения языка, но это требует своих танцев с бубном. Кому интересно, вот видео на эту тему.