telepad: быстрый переход по чатам Telegram из любого окна, как Ctrl+K в Discord

Меню на Rust + rofi, которое открывает в Telegram любой чат, группу, канал, контакт, тему форума или архивный чат — сразу по нескольким аккаунтам — из любого окна в i3. В Telegram нет быстрого перехода уровня Ctrl+K; это моё решение проблемы.

Меню rofi со списком чатов Telegram по нескольким аккаунтам для быстрого перехода

Знакомое чувство: десятки — сотни — чатов, групп, каналов и личных переписок в Telegram, и чтобы найти нужный, приходится скроллить, вспоминать названия и искать внутри приложения. Как тысяча вкладок в браузере, только хуже — они ещё и размазаны по нескольким аккаунтам и закопаны в папки и архив.

Чего я на самом деле хочу: нажать хоткей, набрать пару букв из названия чата, нажать Enter — и я уже там. Ctrl+F в Telegram Desktop — это не оно, это поиск, заточенный под поиск сообщений, и он ведёт себя странно, когда тебе просто надо перейти в диалог. Discord решил это годы назад через Ctrl+K: быстрое меню перехода, где только диалоги и всё сделано под «набрал — Enter — перешёл». В Telegram аналога просто нет.

Поэтому я собрал telepad — небольшую программу на Rust, которая складывает все чаты в меню rofi, вызываемое из любого окна. И раз это глобальный биндинг rofi + i3, получается даже удобнее, чем в Discord: там надо сфокусироваться на Discord → Ctrl+K → набрать → перейти, а тут просто хоткей → набрать → перейти прямо оттуда, где ты уже находишься — из редактора, терминала, браузера. Без переключения контекста и с меньшим числом нажатий.

Стек
Rust, tokio, grammers (MTProto), rofi, D-Bus, xdotool
Задача
Глобальный переход по чатам · темам · архиву Telegram в i3 + rofi, много аккаунтов
Исходники
github.com/antlis/telepad
Статус
Работает-у-меня / раннее
Лицензия
MIT OR Apache-2.0

Что он умеет

Забиндь 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. Пока — воспринимай как рабочий прототип идеи, которая мне нравится.

Попробовать

Terminal window
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, потому что я не стал.