DigitableCourses

X11 · ISC · ранний

digitwm — окна на ленте, а не в сетке.

Окна живут на бесконечной горизонтальной ленте колонок, экран — окно просмотра по этой ленте. Открытие окна двигает ленту, а не сжимает соседей в нечитаемые полоски. Модель как у niri, но на X11 — то есть на Linux, FreeBSD и NetBSD одинаково.

Лента вместо сетки

Тайловый менеджер обычно делит экран между всеми окнами: открыли пятое — четыре предыдущих стали уже. Лента устроена иначе. Колонки стоят в ряд и держат свою ширину, а экран ездит по ним.

01

Колонка держит ширину

Новая колонка встаёт в ленту, соседи разъезжаются вдоль неё, но не сжимаются. Геометрия уже открытого окна при вставке не меняется — это проверяется и арифметически, и на экране.

02

Экран — окно просмотра

Фокус двигает вьюпорт, а не перестраивает ленту. Колонка с фокусом всегда целиком внутри экрана: после фокуса, вставки, закрытия, смены ширины и смены конфигурации мониторов.

03

За краем — не значит закрыто

Уехавшие за край окна остаются отображёнными по координате вне экрана. Гасить их можно настройкой ribbonhide, и цена решения замерена, а не выбрана на глаз.

04

Это не композитор

Анимации нет и не будет: анимация требует процесса, который владеет кадром, а оконный менеджер X11 им не владеет. Окна переезжают за один шаг. Нужны плавные переходы — рядом запускается композитор.

Экран digitwm: три колонки равной ширины. Слева исходный код ribbon.c, посередине спецификация insertion.fts на русском языке, справа документация ribbon.ru.md. У колонки с фокусом подсвечена рамка.
Три колонки по трети экрана: код раскладки, спецификация, по которой он проверяется, и её описание. Ширина колонки переключается по кругу, соседи при этом не сжимаются. Полный размер
Тот же экран с пятью открытыми окнами: три колонки видны целиком, у правого края видна кромка четвёртой, остальные окна ленты находятся за пределами экрана.
Пять открытых окон, видны три: лента длиннее экрана, и это её обычное состояние. Уехавшие за край окна не закрыты и не свёрнуты — они вне окна просмотра. Полный размер
Три колонки с рабочим окружением: слева список наборов инструментов агента Digit с отметками включено и выключено, посередине спецификация FTS с подсветкой синтаксиса, справа список задач taskwarrior по проекту digitwm.
Зачем лента нужна на практике: агент Digit со своими наборами инструментов, спецификация с подсветкой и общий задачник — три окна, между которыми ходишь, а не переключаешься. Подсветка FTS для Vim лежит в репозитории языка, editors/vim-fts. Полный размер
Тот же оконный менеджер с установленным Workbench: три колонки в терминале Alacritty с палитрой Digitable Focus Carbon. Слева файловый менеджер lf, посередине просмотр спецификации через bat с нумерацией строк, справа редактор Vim с подсветкой синтаксиса FTS.
Он же с установленным Workbench: Alacritty, lf, bat и Vim, все в палитре Digitable Focus Carbon. Оконный менеджер тут ни при чём — он бесплатен и работает сам по себе; Workbench настраивает то, что внутри окон. Полный размер

Основа — cwm, и выбрана она не по вкусу

cwm — оконный менеджер из базовой системы OpenBSD, взятый через переносимую сборку. Он маленький, зависит от трёх библиотек и живёт в базе два десятка лет. Но решило не это.

7 883 строки C в апстриме на базовом коммите a343cc9: 7 242 в .c и .h плюс 641 в parse.y.
3 библиотеки в сборке — x11, xft, xrandr. Ни одной добавленной сверх этого.
2 538 строк добавила Digitable в двенадцати файлах: ribbon.c — 968, probe.c — 1 002, остальное — правки в обработке событий и конфигурации.

Главная причина в другом: у cwm нет тайлинга, который пришлось бы выдирать. Это плавающий менеджер, поэтому лента добавляется на чистое место, а не прививается поверх чужого дерева фреймов. Форк сохраняет историю апстрима целиком — 1 146 коммитов, — чтобы авторство читалось из git log, а не только из NOTICE.

Правила раскладки — исполняемые спецификации

Числа, которыми живёт лента, не закопаны в C. Шесть скалярных решений — на сколько уехать после смены фокуса, какой ширины колонка, какой высоты окно в ней, куда вставить новое, что получает фокус после закрытия, что делать со смещением при смене монитора — записаны моделями FTS на двух поверхностях, русской и английской.

Внутри оконного менеджера FTS не исполняется никогда. Модели работают в CI: одни и те же векторы проходят через сгенерированный код и через живой двоичный файл, расхождение валит сборку. Рантайм остаётся на C, yacc и трёх библиотеках X — иначе NetBSD стал бы недостижим.

Три числа, снятые с экрана

Харнесс инвариантов отвечает на вопрос об арифметике. Эти три числа отвечают на вопрос о картинке, и одно из них поймало то, чего арифметика увидеть не могла. Замер: Xvfb 1280×800, программный сервер, двенадцать окон по одному, sh tools/measure-insert.sh -d :91 -n 12 -w 500.

Что мерилиРезультатЧто это значит
Мерцание 0 за 11 вставок Ни одно уже открытое окно не перерисовалось, пока открывалось следующее.
Задержка вставки 2–6 мс от XMapWindow Собственная доля менеджера — принять запрос, выбрать колонку, выдать геометрию. От запуска процесса выходит 5–15 мс, и почти всё это fork, exec и подключение к серверу.
Окна за краем 0 событий UnmapNotify Двенадцать окон на вьюпорте в 1 280 точек: большинство за краем, и ни одно не свёрнуто — ровно это и означает ribbonhide no.

Ноль был не всегда. До коммита 5c4ba49 замер давал одну полную перерисовку на вставку, и ценность замера в том, что он показал причину. Лента ставила новую колонку туда, где стояла старая, и уезжала вьюпортом; новое окно отображалось первым и на несколько миллисекунд накрывало соседа целиком, а содержимое полностью закрытого окна X выбрасывает. Починка — один перенесённый вызов: ribbon_sync() идёт до отображения новичка. Геометрия соседа не менялась ни до, ни после — двигался только x, — поэтому харнесс инвариантов эту беду увидеть не мог: он смотрит на числа, а не на экран.

Чего в этих числах нет

Контрольного образца. Задача DGT-WM-01 просила замерить papersway поверх i3 теми же тремя числами. Он не снят: ни i3, ни papersway на машине нет и в репозиториях дистрибутива их нет, а ставить чужой системный софт ради замера — решение владельца, и задача остаётся открытой ровно на этом. Значит, ни одно число выше ни с чем не сравнено. «digitwm быстрее» здесь не написано и написано не будет, пока сравнивать не с чем.

Лицензия: ISC, и это выбор, а не наследство

digitwm под ISC — дословно тем текстом, что стоит в базовой системе OpenBSD, с девятью строками правообладателей апстрима и одной нашей. Единственное исключение — queue.h под BSD-3-Clause: это sys/queue.h, и он не меняется, чтобы оставаться синхронным с апстримом.

Ни строки из GPL-соседей

papersway (GPL-3.0-or-later), sdorfehs и ratpoison (GPL-2.0-or-later) дают похожий скроллируемый тайлинг. Заимствование оттуда автоматически сдвинуло бы digitwm на копилефт и закрыло бы и путь патчей обратно в cwm, и разрешительную лицензию как таковую. Идеи наблюдать можно, код — нельзя.

В платный архив не входит

И не потому, что лицензия запрещает: ISC разрешает распространение «with or without fee» прямым текстом. Запрет — записанное решение. Разрешительная лицензия заведена ради pkgsrc и портов FreeBSD и NetBSD, а деньги берутся с архива Workbench, оболочки и работы, а не с оконного менеджера.

Забор стережёт сборка

Решение не осталось словами в спецификации. Гейт архива падает, если в поставку попадают исходники, бинарь или узнаваемый код менеджера, и отдельно проверяется, что в дереве оболочки нет ни исходников digitwm, ни линковки с ним: это две программы, которые разговаривают по X11 и по управляющему сокету.

Сессия ничего не вендорит

Каталог session/ настраивает окружение вокруг менеджера — редактор, терминал, мультиплексор, оболочку. Ни один из этих инструментов в репозиторий не кладётся: они ставятся пакетным менеджером системы под своими лицензиями. Своё здесь — только конфигурация и скрипты установки.

Состояние: рано, и вот чего именно нет

Лента есть и проверена — колонки, стопки, вьюпорт, вставка, фокус, пресеты ширины, отдельная лента на каждый выход. Всё остальное честнее перечислить, чем обойти.

Как взять

С голой системы — одной командой; --plan сначала печатает, что произойдёт, и ничего не делает.

git clone https://github.com/digitable-lol/digitwm
cd digitwm
sh bootstrap.sh --plan
sh bootstrap.sh
session/verify.sh
Открыть репозиторий

Документация в репозитории двуязычная: шесть пар документов, русская и английская, и каждый называет, что в нём замерено, а что нет. Начинать стоит с doc/ribbon.md — модель ленты на одной странице — и с doc/baseline.md, где лежат три числа выше вместе с отсутствующим образцом.