Собственный аналог Punto Switcher и Caramba Switcher для macOS: приложение в меню-баре, которое само замечает текст, набранный не в той раскладке («ghbdtn» вместо «привет»), переключает раскладку и перепечатывает слово. Плюс ручное исправление по Option, автозамена по шаблонам и звуки клавиш. Дневника (записи набранного) нет.
- Punto Switcher для Mac (Яндекс) — заброшен: последняя сборка 2.1.2 вышла в ноябре 2017 года, проект заморожен и на современных macOS не работает.
- Caramba Switcher (Сергей Москалёв, автор оригинального Punto) — жива и полностью автоматическая, но закрытая и по подписке (~$6/год в Mac App Store), с самообучением, но без ручных шаблонов.
- Mac Layout Switcher (этот проект) — бесплатный и открытый, весь код у вас. Автоматика + Option-хоткей для ручной конвертации и отката + автозамена по вашим шаблонам + звуки. Без облака, без подписки, без дневника.
- Автоисправление раскладки по детектору (правила невозможных сочетаний + биграммные частоты RU/EN), без ложных срабатываний на коротких/смешанных строках и валидных английских словах.
- Исправление до отправки: Enter/пробел/Tab перехватываются раньше, чем их увидит приложение. Если слово надо исправить — оно перепечатывается, раскладка переключается, и только потом разделитель доходит до приложения. В чатах (Telegram, Slack, iMessage) Enter отправляет уже исправленное сообщение, а не опечатку. Если исправлять нечего — клавиша проходит как есть, без задержки. Shift+Enter (перенос строки) сохраняется.
- Option (одиночное нажатие-отпускание) — сконвертировать последнее слово RU↔EN вручную; Option сразу после авто-исправления — откатить его, и слово попадает в исключения (больше не трогается).
- Автопауза в полях паролей (secure input) и в приложениях-исключениях
(по умолчанию Terminal, iTerm2, VS Code — правится в
config.json). - Автозамена по шаблонам: «сдр» + пробел → «С днём рождения!».
- Звуки: отдельные сигналы на исправление и на откат (обычные нажатия не озвучиваются).
-
macOS 13 (Ventura) или новее, Intel или Apple Silicon.
-
Swift toolchain — Xcode Command Line Tools:
xcode-select --install
Одной командой из корня репозитория (на своём Mac):
./build.shСкрипт соберёт релиз через SwiftPM, разложит dist/MacLayoutSwitcher.app
(с LSUIElement — без иконки в Dock) и подпишет его ad-hoc. В конце напечатает
путь и дальнейшие шаги.
Иконка приложения: исходник — Resources/AppIcon.svg, готовый
Resources/AppIcon.icns лежит в репозитории и попадает в бандл автоматически;
после правки SVG пересобрать его командой python3 tools/make-icns.py
(нужен cairosvg).
Логику детектора можно проверить ещё до сборки .app — на любой машине, включая Linux (это же гоняет CI сборки):
swift testЧтобы получить приложение как полноценный дистрибутив — образ, который
монтируется и ставится перетаскиванием в «Программы», — соберите .dmg
(на своём Mac, одной командой):
./build-dmg.shСкрипт сначала соберёт dist/MacLayoutSwitcher.app через ./build.sh (если
его ещё нет; --rebuild пересобирает принудительно), затем упакует его в
dist/MacLayoutSwitcher.dmg с ярлыком «Программы» (Applications) внутри.
Дальше:
open dist/MacLayoutSwitcher.dmg— смонтировать образ.- Перетащить MacLayoutSwitcher.app на ярлык «Программы» (Applications).
Приложение подписано только ad-hoc (нет Apple Developer ID, нет нотаризации — это личная сборка), поэтому первый запуск после установки:
- В «Программах» правый клик по MacLayoutSwitcher → «Открыть» → в диалоге Gatekeeper подтвердить «Открыть» (обычный двойной клик macOS может отклонить). Это нужно один раз; дальше приложение запускается как обычно.
- Затем выдать те же два разрешения, что и для .app — Универсальный доступ (Accessibility) и Мониторинг ввода (Input Monitoring) — см. раздел «Первый запуск и разрешения» ниже.
- Запустить:
open dist/MacLayoutSwitcher.app. Из-за ad-hoc подписи Gatekeeper может отказать при двойном клике — тогда правый клик по .app → «Открыть» (один раз). - Приложение слушает клавиатуру во всех программах, поэтому macOS требует два
разрешения. Приложение покажет подсказку с кнопками; выдать вручную можно
так:
Системные настройки → Конфиденциальность и безопасность →
- Универсальный доступ (Accessibility) — включить «MacLayoutSwitcher».
- Мониторинг ввода (Input Monitoring) — включить «MacLayoutSwitcher».
- Перезапустить приложение (пункт меню-бара «Я выдал разрешения» или заново
open). В меню-баре появится индикатор раскладки («RU»/«EN»).
В самом меню-баре приложение показывает текущую раскладку текстом — жирное RU или EN (неопознанный источник, например IME, — «--»). Индикатор меняется сразу при любой смене раскладки: сами переключились (⌃Space, меню ввода), сработало авто-исправление или Option-конвертация. Обновление событийное (системное уведомление смены источника ввода), без поллинга. В паузе индикатор приглушён: серый, с префиксом «⏸».
Пункты меню:
- Пауза / Работа — временно выключить перехват (индикатор приглушается).
- Автопереключение — вкл/выкл авто-исправление по детектору.
- Звуки — вкл/выкл озвучку.
- Запускать при входе — автозапуск после перезагрузки Mac (см. ниже).
- Открыть snippets.json / config.json — правка шаблонов и настроек во внешнем редакторе (после правки Engine перечитывает файлы).
- Горячие клавиши… — окно настройки горячих клавиш (см. ниже).
- Проверить обновления… — ручная проверка новой версии (см. «Автообновление»).
- О программе, Выход.
Все тумблеры пишутся в config.json сразу и переживают перезапуск.
Пункт меню-бара «Горячие клавиши…» открывает окно с двумя строками:
- Конвертация / откат — клавиша ручного исправления RU↔EN и отката авто-исправления. По умолчанию Option (одиночный tap) — как было раньше.
- Вкл/выкл авто — клавиша, включающая/выключающая автопереключение. По умолчанию не назначена.
У каждой строки — текущее значение, кнопка «Записать» (нажмите нужное сочетание — одиночный модификатор вроде Option/Caps Lock или клавишу с модификаторами, например ⌘⇧K; Esc отменяет запись) и «Сброс» (вернуть значение по умолчанию).
Выбор сохраняется в config.json (поля convertHotkey / toggleAutoHotkey) и
применяется сразу; для надёжности после смены можно перезапустить приложение.
Старый config.json без этих полей грузится с дефолтами — обновление ничего не
ломает.
Пункт меню-бара «Запускать при входе» включает автостарт приложения после
перезагрузки Mac (входа в систему). По умолчанию выключено. Галочка
показывает фактическое состояние: под капотом — SMAppService.mainApp
(macOS 13+), поэтому источник истины — сама система, а не config.json.
- Если регистрация не удалась (macOS отказала) — галочка возвращается в прежнее положение, ложного «включено» не будет.
- На современных macOS система может попросить подтвердить автозапуск вручную: при включении появится подсказка и откроется панель Объекты входа — включите там «Mac Layout Switcher», иначе автостарт не заработает (это не ошибка, а штатное подтверждение).
- Отключить автозапуск можно и вне приложения: Системные настройки → Основные → Объекты входа, там же он появится под именем приложения. Если вы сняли его там, приложение при следующем старте это заметит и снимет галочку.
- Замечание про ad-hoc-подпись: у неподписанной сборки объект входа в Системных настройках может отображаться как «Программа» без внятного имени — это нормально для личной сборки без нотаризации.
Приложение само следит за новыми версиями (репозиторий публичный, версия —
файл VERSION в корне репо, semver):
- Как проверяет. Через ~1 минуту после запуска и дальше раз в 24 часа
приложение сравнивает свою версию (из
Info.plist, туда её кладётbuild.shиз файлаVERSION) с rawVERSIONиз веткиmainна GitHub. Есть новее — алерт «Доступна версия X. Обновить?» с кнопками Обновить / Позже. Нет новее или нет сети — молчит (сетевые сбои видны только в системном логе). Пункт меню «Проверить обновления…» делает то же самое вручную и, в отличие от фоновой проверки, отвечает и «Версия актуальна». - Как обновляется. По кнопке «Обновить» приложение запускает скрипт
self-update.sh(лежит вContents/Resourcesбандла; выполняется его копия из временной папки) и выходит. Скрипт скачиваетmain.tar.gzс GitHub, собирает./build.shво временной папке, и только после успешной сборки заменяет установленный.appпо прежнему пути и открывает новую версию. Любой сбой (сеть, сборка) оставляет текущую установку нетронутой. - Лог: весь ход обновления — в
~/Library/Logs/MacLayoutSwitcher-update.log(загляните туда, если после «Обновить» приложение не вернулось за пару минут). - Разрешения придётся выдать заново. Замена
.appс ad-hoc-подписью сбрасывает доверие TCC: при первом старте новой версии macOS снова попросит Универсальный доступ и Мониторинг ввода — сработает обычный онбординг. Это плата за обновление без сертификата разработчика; алерт обновления предупреждает об этом заранее.
Файл ~/Library/Application Support/MacLayoutSwitcher/snippets.json — простой
JSON «сокращение → раскрытие». Разворачивается по разделителю (пробел/enter):
{
"сдр": "С днём рождения!",
"ттт": "тел.: +7 000 000-00-00"
}Пункт меню «Открыть snippets.json» создаёт файл-заготовку, если его ещё нет.
После выдачи разрешений прогнать по пунктам (галочка = работает):
- В TextEdit набрать
ghbdtn+ пробел → превращается впривет, раскладка переключилась на русскую. - Набрать
cgfcb,j+ пробел →спасибо(пунктуация внутри слова не считается границей). - Валидное английское слово
hello+ пробел → не тронуто. - Короткие/смешанные строки (
ok,id,wifi2, e-mail) → не тронуты. - Набрать слово в неправильной раскладке, нажать Option → слово сконвертировано вручную, раскладка сменилась.
- Сразу после авто-исправления нажать Option → вернулось как было; повторный набор того же слова больше не исправляется автоматически.
- Поле пароля в Safari (secure input) → автоматика молчит, ничего не перепечатывается.
- Terminal (приложение-исключение) → автоматика молчит.
- Шаблон
сдр+ пробел → развернулся в «С днём рождения! ». - Включить Звуки: обычный набор — тишина, на исправление и на откат — отдельные сигналы; выключить — тишина всегда.
- Поставить Паузу — перехват прекращается, индикатор в меню-баре серый с «⏸»; снять — снова работает.
- Перезапустить приложение → состояние тумблеров (автопереключение, звуки, исключения) сохранилось.
- Индикатор в меню-баре показывает RU/EN и меняется сразу: при ⌃Space (ручная смена), при авто-исправлении и при Option-конвертации.
- В чате (Telegram/Slack/Сообщения) набрать
j,yjdbkczи нажать Enter → отправляется «обновился», а неj,yjdbkcz; в поле ничего не остаётся.hello+ Enter → уходит сразу, без паузы. Shift+Enter после слова с опечаткой → слово исправлено, строка перенесена, сообщение НЕ отправлено. -
ghbdtn+ Tab в форме (два поля) → «привет» в первом поле, фокус ушёл во второе.
Нет дневника и авто-самообучения (только ручные исключения + автодобавление при откате), нет GUI-редактора шаблонов (правятся как JSON), нет подписи/ нотаризации (личная сборка на своём Mac). Пары языков — RU/EN; ядро расширяемо.