Перевести выделенное
Пилюля появляется мгновенно, у курсора со смещением 12 × 16 px, и пружиной раскрывается в карточку. Esc закрывает без анимации.

Выделил текст, нажал три клавиши, и перевод появился у курсора. Без вкладок, ключей и регистрации.
Скачать на GitHub
Выделил, скопировал, ушёл во вкладку, вставил, вернулся и потерял строку. Хотелось, чтобы перевод появлялся там, где читаешь, и исчезал, когда больше не нужен.
Ориентиром был QTranslate: работал в любой программе, но перестал обновляться. UTranslate повторяет его поведение на Tauri 2, Rust и React.
Ожидание показано внутри карточки, а не отсутствием карточки.
Захват через Ctrl+C: так программа достаёт текст из браузера, мессенджера и редактора.
Три движка работают без ключей. Ключ нужен только для улучшения через модель.
Буфер обмена после работы такой же, как до. Если поле изменилось, вставка отменяется.
Выдели абзац мышью или нажми CtrlAltTНажми на абзац
A good tool disappears. You stop thinking about the translator and keep reading the page you came for.
Press the shortcut once and the answer shows up right next to your cursor, not in another tab.
If one engine fails, the next one quietly takes over, so the translation still arrives.
Копия капсулы в той же логике: пилюля, пружина, заглушка, текст, замена на месте. Попробуй заменить абзац, а потом выделить его снова: направление сменится само.
Пилюля появляется мгновенно, у курсора со смещением 12 × 16 px, и пружиной раскрывается в карточку. Esc закрывает без анимации.
Написал по-русски, нажал, и в поле английский. Изменилось окно или выделение, значит вставка отменяется.

Сочетание переназначается в настройках. Занятое другой программой помечается сразу, при попытке назначить.
Попап в роликах настоящий: тот же код программы, снятый покадрово с частотой 60 кадров в секунду. Страница и поле вокруг него собраны для съёмки.


А это живые кадры со стенда: Chrome на Windows, настоящий перевод абзаца из Википедии.
Картинка, видео, игра. Экран замирает, ты обводишь область, и перевод встаёт под ней. Если снизу места нет, то над ней, чтобы не закрывать текст.

Выделите область с текстомEsc отмена · Enter вся табличка
На странице настоящее только выделение, перевод записан заранее. В программе оверлей нативный, на Win32 и GDI+: текст распознаёт PP-OCRv5 на компьютере.
Не пишется на диск, не попадает в буфер обмена и в сеть. В движок уходит только распознанный текст.
Windows.Media.Ocr требует package identity, новый Windows AI работает только с NPU. Модели идут в сборке, около 60 МБ в памяти, через три минуты простоя выгружаются.
Затемнение 40 %, рамка 2 px, без прицела. Движения нет, только прозрачность: вход 120 мс, выход 90 мс, Esc мгновенно.
Настоящие кадры интерфейса, тот же код программы. Правило из требований: действие без видимого ответа считается сломанным.




Карточка видна сразу, текст приходит в неё.


Одно или два слова: значения по частям речи.


Первый движок молчит. Бейдж говорит, кто ответил.


Улучшение через Groq или OpenRouter по своему ключу.


Другой движок для этого же текста.


Оригинал раскрывается над переводом.


Перевод можно поправить до вставки.


С экрана: вставлять некуда, поэтому «Выделить заново».
Ctrl+Alt+W. История живёт на компьютере в SQLite, избранное выгружается в CSV. DWM скругляет окно максимум на 8 px, поэтому окно прозрачное, а радиус 18 и тень рисует сам интерфейс.










Листай снимок вбок. Окно шириной 960 px, на телефон его целиком не положить.
Ответил Google




Чтобы взять текст из любой программы, приходится самому нажать Ctrl+C, то есть залезть в чужой буфер. Правило из требований: забрать и положить обратно так, чтобы человек не заметил.
Формат, который нельзя прочитать, пропускается, захват не падает.
Ждём физического отпускания, до 1,5 с. Иначе T упадёт в чужое поле.
Через SendInput: программа сама нажимает сочетание вместо человека.
До 0,7 с. Номер не сменился, значит выделения не было.
Текст взят, буфер восстановлен. Перевод не ждёт этого шага.
Чужой формат с отложенной отрисовкой нельзя прочитать, и один он срывал весь захват. Теперь снимок буфера делается по возможности: такие форматы пропускаются.
При переводе с экрана терялись 1–3 буквы каждой строки. Винили распознавание, но на тех же кропах оно было чистым. Виноват оверлей: якорь выделения брался из GetCursorPos, а не из lParam.
PowerShell записал settings.json с BOM, Rust молча взял значения по умолчанию, и хоткей перестал работать. Теперь BOM срезается, а невалидное поле чинится отдельно от остальных.
В журнале решений проекта 57 развилок, каждая с причиной.


WebView2 не размывает то, что под окном. Системный акрил размывает весь прямоугольник окна вместе с полем под тень. Настоящее стекло стоило бы снимка экрана под каждым показом, поэтому от него отказались и перерисовали всё матовым.
Рендеры 16, 24, 32 и 48 px рядом со значками Telegram, Discord и Steam на обеих панелях задач. Они тоже сине-зелёные, поэтому решают силуэт и белое пятно. Реплика со стрелкой к тому же и есть продукт: попап у курсора.
Лаванда не из палитры. Капсула — форма попапа, а не программы.
На 16 px шов исчезает, в ряду читается как батарея.
Диагональ на 16 px расплывается.
Повторяет кнопку «поменять языки» в собственном окне.
На 16 px буква схлопывается в клин.
Просветы букв меньше пикселя, на 16 px каша.
