t3h Switcher
Утилита для macOS, которая делает работу с раскладкой клавиатуры удобной: мгновенная конвертация текста, переключение раскладки одной горячей клавишей и автоматическое запоминание языка ввода для каждого приложения.
🔄 Конвертация текста по ⌥ (Option)
Набрали текст в неправильной раскладке? Нажмите ⌥ — и слово мгновенно превратится в правильное:
| Было (неверная раскладка) | Стало (после ⌥) |
|---|---|
ghbdtn | привет |
привет | ghbdtn |
Ytpyf. | Незнаю |
Утилита сама определяет направление конвертации — по первому буквенному символу. Если текст был кириллицей — конвертирует в латиницу, и наоборот.
Как это работает
- Выделяется слово слева от курсора (эмуляция ⌥⇧←).
- Копируется в буфер обмена (⌘C).
- Конвертируется по словарю QWERTY ↔ ЙЦУКЕН.
- Вставляется вместо старого (⌘V).
- Курсор возвращается в конец вставленного слова.
- Буфер обмена восстанавливается (опционально).
- Работает с выделенным текстом и с последним набранным словом.
- Защита от конвертации слишком длинных фрагментов (до 100 символов).
- Поддержка заглавных букв, цифр и знаков препинания.
⌨️ Переключение раскладки по ⌃⇧ (Control + Shift)
Нажмите ⌃⇧ в любой момент — раскладка мгновенно сменится между русской и английской.
В отличие от стандартного ⌃Space или 🌐Space, используется прямое переключение через TIS API (TISSelectInputSource) — раскладка меняется синхронно и мгновенно, без задержек и багов отката, характерных для эмуляции системных сочетаний.
- Не конфликтует с другими приложениями.
- Работает даже там, где системное сочетание игнорируется.
- Не оставляет «залипших» раскладок.
🧠 Автоматическое запоминание раскладки для каждого приложения
Каждое приложение запоминает свою раскладку и восстанавливает её при следующем переходе:
- В Xcode вы печатаете по-русски — при переключении из других окон раскладка вернётся на русскую.
- В iTerm2 у вас английская — при возврате в терминал язык автоматически переключится на английский.
- В Safari — та, которую вы использовали в последний раз.
- Если вы сменили раскладку вручную (
⌃Space, клик в меню-баре) — утилита это заметит и тоже запомнит.
Как это работает
- Отслеживается смена активного приложения через
NSWorkspace. - Раскладка проверяется с частотой 0.2 сек (нагрузка на CPU — менее 0.1%).
- Используется «опрос-петля» для быстрой реакции после активации окна (50–100 мс).
- Память хранится в оперативной памяти (можно включить сохранение между запусками).
🔀 Автосмена раскладки после конвертации
После конвертации текста раскладка ввода автоматически меняется на ту, в которую вы сконвертировали:
- Набрали
ghbdtnв английской раскладке → нажали ⌥. - Текст превратился в
привет, и раскладка переключилась на русскую. - Дальше печатаете — сразу идёт кириллица, ничего переключать не нужно.
Обратно — тоже работает: после конвертации привет → ghbdtn раскладка становится английской.
🎛️ Значок в трее
Утилита живёт только в строке меню и не засоряет Dock. Клик по иконке открывает меню:
- Настройки… (⌘,) — параметры поведения
- О программе — информация об авторе и версии
- Выход (⌘Q) — завершение работы
Иконка в трее — статичная (character.book.closed). В дальнейшем можно сделать её отражающей текущую раскладку («RU» / «EN»).
⚙️ Настройки
Окно настроек открывается из меню трея (⌘,):
| Параметр | Описание |
|---|---|
| Восстанавливать буфер обмена | После конвертации возвращает в буфер то, что там было до этого |
| Макс. длина текста | Верхний порог количества символов для конвертации (по умолчанию 100) |
🔐 Разрешения
Для работы утилиты требуется разрешение Универсальный доступ (Accessibility):
- Системные настройки → Конфиденциальность и безопасность → Универсальный доступ.
- Также может потребоваться Мониторинг ввода (Input Monitoring) для перехвата клавиш.
Без этих разрешений CGEventTap не сможет перехватывать нажатия ⌥ и ⌃⇧, а приложение — эмулировать ⌘C / ⌘V.
Важно: после обновления приложения (или смены Bundle Identifier) разрешение может слететь — нужно выдать его заново.
🖥️ Системные требования
| ОС | macOS 14 (Sonoma) и новее, включая macOS 26/27 |
| Архитектура | Apple Silicon (arm64) |
| Размер | ~1–2 МБ |
| Потребление CPU | <0.5% в фоне |
| Потребление RAM | ~20–30 МБ |
| Зависимости | Отсутствуют (нативный Swift + SwiftUI) |
🧩 Технические детали
Архитектура
t3h Switcher/
├── t3h_switcherApp.swift ← точка входа, MenuBarExtra, колбэки
├── ContentView.swift ← меню трея
├── SettingsView.swift ← окно настроек
├── KeyboardMonitor.swift ← CGEventTap, перехват ⌥ и ⌃⇧
├── TextConverter.swift ← словари QWERTY ↔ ЙЦУКЕН
├── TextReplacer.swift ← ⌥⇧← → ⌘C → конверт → ⌘V → →
├── LayoutSwitcher.swift ← TIS API, прямое переключение
└── LayoutMemoryManager.swift ← память раскладок по приложениям
Используемые технологии
- SwiftUI — интерфейс (MenuBarExtra, Settings, ContentView).
- Core Graphics (CGEventTap, CGEvent) — глобальный перехват и эмуляция клавиш.
- Carbon (TIS API) — получение ID текущей раскладки и прямое переключение.
- AppKit (NSWorkspace, NSPasteboard, NSApplication) — работа с приложениями, буфером, окнами.
- UserDefaults — хранение пользовательских настроек.
Ключевые решения
- CGEventTap вместо RegisterEventHotKey — позволяет перехватывать одиночные нажатия модификаторов (⌥, ⌃⇧), которые Carbon не поддерживает.
- TISSelectInputSource вместо эмуляции ⌃Space — синхронное переключение раскладки без задержек и багов.
- Опрос раскладки по таймеру вместо notification —
keyboardSelectionDidChangeNotificationприходит не всегда. - Poll-петля для смены приложений — реакция за 50–100 мс вместо фиксированной задержки 200–300 мс.
💡 Идеи для развития
- 💾 Сохранение памяти раскладок между запусками (сейчас — только в оперативной памяти).
- 🎨 Иконка в трее с текущей раскладкой («RU» / «EN»).
- ⚙️ Настраиваемые горячие клавиши вместо жёстко зашитых ⌥ и ⌃⇧.
- 📋 Список исключений — приложения, где утилита не работает.
- 🔔 Уведомление-индикатор при переключении раскладки.
- 🚀 Автоконвертация по образцу Punto Switcher — без нажатия ⌥.
- 🌍 Поддержка других раскладок (украинская, немецкая, французская).