Skip to content

Repository files navigation

Mac Layout Switcher

Собственный аналог Punto Switcher и Caramba Switcher для macOS: приложение в меню-баре, которое само замечает текст, набранный не в той раскладке («ghbdtn» вместо «привет»), переключает раскладку и перепечатывает слово. Плюс ручное исправление по Option, автозамена по шаблонам и звуки клавиш. Дневника (записи набранного) нет.

Чем отличается от Punto и Caramba

  • 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.appLSUIElement — без иконки в Dock) и подпишет его ad-hoc. В конце напечатает путь и дальнейшие шаги.

Иконка приложения: исходник — Resources/AppIcon.svg, готовый Resources/AppIcon.icns лежит в репозитории и попадает в бандл автоматически; после правки SVG пересобрать его командой python3 tools/make-icns.py (нужен cairosvg).

Логику детектора можно проверить ещё до сборки .app — на любой машине, включая Linux (это же гоняет CI сборки):

swift test

Установка через .dmg

Чтобы получить приложение как полноценный дистрибутив — образ, который монтируется и ставится перетаскиванием в «Программы», — соберите .dmg (на своём Mac, одной командой):

./build-dmg.sh

Скрипт сначала соберёт dist/MacLayoutSwitcher.app через ./build.sh (если его ещё нет; --rebuild пересобирает принудительно), затем упакует его в dist/MacLayoutSwitcher.dmg с ярлыком «Программы» (Applications) внутри.

Дальше:

  1. open dist/MacLayoutSwitcher.dmg — смонтировать образ.
  2. Перетащить MacLayoutSwitcher.app на ярлык «Программы» (Applications).

Приложение подписано только ad-hoc (нет Apple Developer ID, нет нотаризации — это личная сборка), поэтому первый запуск после установки:

  • В «Программах» правый клик по MacLayoutSwitcher → «Открыть» → в диалоге Gatekeeper подтвердить «Открыть» (обычный двойной клик macOS может отклонить). Это нужно один раз; дальше приложение запускается как обычно.
  • Затем выдать те же два разрешения, что и для .app — Универсальный доступ (Accessibility) и Мониторинг ввода (Input Monitoring) — см. раздел «Первый запуск и разрешения» ниже.

Первый запуск и разрешения

  1. Запустить: open dist/MacLayoutSwitcher.app. Из-за ad-hoc подписи Gatekeeper может отказать при двойном клике — тогда правый клик по .app → «Открыть» (один раз).
  2. Приложение слушает клавиатуру во всех программах, поэтому macOS требует два разрешения. Приложение покажет подсказку с кнопками; выдать вручную можно так: Системные настройки → Конфиденциальность и безопасность →
    • Универсальный доступ (Accessibility) — включить «MacLayoutSwitcher».
    • Мониторинг ввода (Input Monitoring) — включить «MacLayoutSwitcher».
  3. Перезапустить приложение (пункт меню-бара «Я выдал разрешения» или заново 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) с raw VERSION из ветки 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 снова попросит Универсальный доступ и Мониторинг ввода — сработает обычный онбординг. Это плата за обновление без сертификата разработчика; алерт обновления предупреждает об этом заранее.

Шаблоны автозамены (snippets.json)

Файл ~/Library/Application Support/MacLayoutSwitcher/snippets.json — простой JSON «сокращение → раскрытие». Разворачивается по разделителю (пробел/enter):

{
  "сдр": "С днём рождения!",
  "ттт": "тел.: +7 000 000-00-00"
}

Пункт меню «Открыть snippets.json» создаёт файл-заготовку, если его ещё нет.

Чек-лист ручной приёмки на Mac

После выдачи разрешений прогнать по пунктам (галочка = работает):

  1. В TextEdit набрать ghbdtn + пробел → превращается в привет , раскладка переключилась на русскую.
  2. Набрать cgfcb,j + пробел → спасибо (пунктуация внутри слова не считается границей).
  3. Валидное английское слово hello + пробел → не тронуто.
  4. Короткие/смешанные строки (ok, id, wifi2, e-mail) → не тронуты.
  5. Набрать слово в неправильной раскладке, нажать Option → слово сконвертировано вручную, раскладка сменилась.
  6. Сразу после авто-исправления нажать Option → вернулось как было; повторный набор того же слова больше не исправляется автоматически.
  7. Поле пароля в Safari (secure input) → автоматика молчит, ничего не перепечатывается.
  8. Terminal (приложение-исключение) → автоматика молчит.
  9. Шаблон сдр + пробел → развернулся в «С днём рождения! ».
  10. Включить Звуки: обычный набор — тишина, на исправление и на откат — отдельные сигналы; выключить — тишина всегда.
  11. Поставить Паузу — перехват прекращается, индикатор в меню-баре серый с «⏸»; снять — снова работает.
  12. Перезапустить приложение → состояние тумблеров (автопереключение, звуки, исключения) сохранилось.
  13. Индикатор в меню-баре показывает RU/EN и меняется сразу: при ⌃Space (ручная смена), при авто-исправлении и при Option-конвертации.
  14. В чате (Telegram/Slack/Сообщения) набрать j,yjdbkcz и нажать Enter → отправляется «обновился», а не j,yjdbkcz; в поле ничего не остаётся. hello + Enter → уходит сразу, без паузы. Shift+Enter после слова с опечаткой → слово исправлено, строка перенесена, сообщение НЕ отправлено.
  15. ghbdtn + Tab в форме (два поля) → «привет» в первом поле, фокус ушёл во второе.

Границы этой версии

Нет дневника и авто-самообучения (только ручные исключения + автодобавление при откате), нет GUI-редактора шаблонов (правятся как JSON), нет подписи/ нотаризации (личная сборка на своём Mac). Пары языков — RU/EN; ядро расширяемо.

About

Аналог Punto/Caramba Switcher для macOS: авто-исправление раскладки RU/EN, настраиваемые хоткеи, автозамена, .dmg

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages