telepad: быстрый переход по чатам Telegram из любого окна, как Ctrl+K в Discord
Меню на Rust + rofi, которое открывает в Telegram любой чат, группу, канал, контакт, тему форума или архивный чат — сразу по нескольким аккаунтам — из любого окна в i3. В Telegram нет быстрого перехода уровня Ctrl+K; это моё решение проблемы.
Знакомое чувство: десятки — сотни — чатов, групп, каналов и личных переписок в Telegram, и чтобы найти нужный, приходится скроллить, вспоминать названия и искать внутри приложения. Как тысяча вкладок в браузере, только хуже — они ещё и размазаны по нескольким аккаунтам и закопаны в папки и архив.
Чего я на самом деле хочу: нажать хоткей, набрать пару букв из названия чата, нажать Enter — и я уже там. Ctrl+F в Telegram Desktop — это не оно, это поиск, заточенный под поиск сообщений, и он ведёт себя странно, когда тебе просто надо перейти в диалог. Discord решил это годы назад через Ctrl+K: быстрое меню перехода, где только диалоги и всё сделано под «набрал — Enter — перешёл». В Telegram аналога просто нет.
Поэтому я собрал telepad — небольшую программу на Rust, которая складывает все чаты в меню rofi, вызываемое из любого окна. И раз это глобальный биндинг rofi + i3, получается даже удобнее, чем в Discord: там надо сфокусироваться на Discord → Ctrl+K → набрать → перейти, а тут просто хоткей → набрать → перейти прямо оттуда, где ты уже находишься — из редактора, терминала, браузера. Без переключения контекста и с меньшим числом нажатий.
Что он умеет
Забиндь telepad на клавишу в i3 (у меня Super+g — «g» как go
to chat), и получается глобальный переключатель:
- Фаззи-переход к любому чату, группе, каналу или контакту — включая тех, кто тебя заблокировал, и людей, с кем нет открытого диалога — сразу по всем аккаунтам в одном плоском списке.
- Темы форумов — каждая тема это отдельная строка для поиска (
Форум ▸ Тема), так что можно перейти в неё сразу с первого набора; а при выборе самого форума по-прежнему открывается второе меню с его темами. - Папки — каждая папка это строка
📁 <Папка>, которая раскрывается во второе меню с чатами этой папки. - Архив — пункт
🗄 Archivedна каждый аккаунт: открыть папку архива или сразу перейти в конкретный архивный чат. - Много аккаунтов — перед открытием переключается на нужный.
Список чатов один раз читается через grammers (MTProto-клиент на Rust) и кэшируется в JSON; меню читает кэш, поэтому открывается мгновенно.
Это в том же духе, что и brave-rofi-rust, который решает браузерную версию этой же проблемы — переход к любой вкладке, закладке или записи истории из любого окна. Та же идея, другое приложение.
Две проблемы, которых я не ждал
Меню оказалось лёгкой частью. А вот управление Telegram снаружи превратилось в небольшую детективную историю — стоит записать, потому что причины у обеих проблем неочевидные.
Открыть чат через xdg-open нельзя. Очевидный способ открыть ссылку tg:// — это
xdg-open, но он запускает второй процесс Telegram, и его single-instance-передача
конфликтует с уже запущенным — у меня это просто каждый раз убивало открытое окно.
Решение — доставлять ссылку внутрь процесса по D-Bus
(org.freedesktop.Application.Open), который отдаёт её уже запущенному экземпляру и
ничего нового не порождает. Для чатов без публичного юзернейма (приватные группы,
часть личек) ссылки t.me нет, поэтому telepad открывает их по внутреннему id пира
через обработчик AyuGram tg://chat?id=.
Переключение аккаунта роняет обработчик диплинков. Параметр tg://…&acc=N должен
переключать аккаунт перед открытием. На проверенных мной сборках он крашит клиент
(молча — на Nix-сборке даже без крэш-дампа). А так как единственный другой способ
переключиться — запустить второй процесс (см. выше), который убивает приложение,
безопасного способа переключить аккаунт через ссылку не остаётся вообще.
Поэтому переключение аккаунта сделано в лоб: telepad фокусирует окно и эмулирует
нажатие той клавиши, что ты забиндил в клиенте на этот аккаунт (например,
Alt+2), через xdotool — ровно то переключение, что ты сделал бы
руками, и оно-то безопасно. Некрасиво, требует X11, а windowactivate у самого
xdotool виснет в i3 (ждёт _NET_WM_DESKTOP, которого i3 не выставляет), так что
фокус отдаётся i3-msg, а через xdotool идёт только само нажатие. Не изящно, но
работает и полностью обходит краш.
Как оно есть
Честно, как и в прошлый раз: это личный инструмент, заточенный под моё окружение.
- Только Linux + i3 + X11 + rofi + xdotool. Переключение аккаунтов держится на эмуляции клавиш в X11; на Wayland нужен другой инжектор. Не задавай клавишу переключения — и всё работает в пределах одного аккаунта и с куда меньшим числом зависимостей.
- Тестировалось с AyuGram, не с обычным Telegram Desktop.
Обработчики
tg://и D-Bus-имяcom.ayugram.desktopспецифичны для AyuGram; у Telegram Desktop другое имя и нет обработчикаtg://chat?id=. Поддержать оба — вроде бы небольшая правка, просто пока руки не дошли. - Отдельная сессия. grammers логинится независимо от клиента (отдельным «устройством» в списке сессий) только чтобы прочитать список чатов — к зашифрованным локальным данным клиента он доступа не имеет.
И, как и с brave-rofi-rust: может, когда-нибудь придумаю что-то более осмысленное и менее прибитое к этой конкретной куче зависимостей — один самодостаточный бинарник со своим меню и WM-независимым способом фокусировать окно и переключать аккаунт, чтобы не зависеть от rofi, i3 и xdotool. Пока — воспринимай как рабочий прототип идеи, которая мне нравится.
Попробовать
cargo install --git https://github.com/antlis/telepad.gitПолучи api_id/api_hash на my.telegram.org, положи
конфиг в ~/.config/telepad/config.toml, один раз сделай telepad login <account> на
каждый аккаунт, затем telepad sync и забиндь в i3:
bindsym $mod+g exec --no-startup-id telepadВ README — полная конфигурация, настройка переключения аккаунтов и текущий список шероховатостей. Issue и PR приветствуются — особенно если прикрутишь поддержку обычного Telegram Desktop, потому что я не стал.