commit -m "better"
2.96K subscribers
868 photos
105 videos
3 files
2.07K links
just random thoughts
Download Telegram
В одном там рабочем чате с коллегами зашла речь, кто как смотрит порно. Мне пришлось признаться, что я для этого использую рабочий macbook, потому что в моем браузере все еще не работает поддержка видео. Собственно, у меня там 3 заметных проблемы:

1) Поддержка видео. Как починю, обязательно напишу про эту эпичную историю.
2) Про кривые иконки из-за старой librsvg я уже писал, надо или как-то затащить Rust, или научить это оффлоадить в inkscape. Я склоняюсь ко второму пути.
3) И сегодняшняя история - поддержка PDF!

Epiphany, как и многие, поддерживает PDF через PDF.JS. Но оно почему-то не работает. Конечно, как обычно, дело в динамическом связывании - код, которому нужен код читалки, не может его найти в runtime. И в данном случае дело не в статической линковке, а в чем-то еще(что-то с ресурсной системой glib, я не разобрался пока).

Чинить это займет время, а pdf-ки читать надо уже сейчас.

Я решил вечерочком собрать себе читалку - Evince. Думал, плевое дело, простая программа, все зависимости уже в репе, 5 минут, не больше. Ага, конечно.

* В программе есть плагины. Читатели у меня уже прошаренные, поэтому я просто скажу, что загрузка плагинов там по второму типу #plugins Плагины много времени не заняли, все же, это основная фишка дистрибутива.

* После загрузки программы я увидел надпись "unsupported mime type application/octet-stream", и тут я понял, что это надолго.

Не буду утомлять скучными подробностями #debug, но:

* glib неявно зависит от базы данных для определения mime types. Неявно - значит, все делает вид, что работает, до поры до времени, примерно как TLS в той же #glib.

* Пути для поиска этих данных вычисляются довольно нетривиальным образом.

* Самое страшное - сборка этих данных зависит от docbook xml, а это моя дикая боль. Я напишу об этом отдельно, но надо понимать, что там очень сложная динамическая линковка данных поверх XML, все это сдобрено perl, с легким налетом GNU. Я это затащить могу, но очень не хочу, и пока просто обходил стороной. А тут жесткая зависимость сборки.

Короче, я решил, что вместо всей этой херни я вкорячу старую-добрую libmagic, из пакета file https://www.darwinsys.com/file/. Хороший, древний, проверенный код, без изъебов.

revision 1.1
date: 1987/08/23 19:51:05; author: ian; state: Exp;
Initial revision


Код чуть младше меня.

Замечания по ходу процесса:

* Пришлось сделать thread-safe обертку над api libmagic: https://github.com/pg83/mix/blob/main/pkgs/lib/mimetype/mix.sh

* Как оно используется: https://github.com/pg83/mix/blob/main/pkgs/lib/glib/01.diff (блин, а код без аллокаций на C писать вполне норм!) Я бы хотел тут остановиться, и сказать, что оно заработало like a charm, но нет

* glib сначала пытается определить тип по расширению, в #libmagic этого нет. Я это обошел тем, что всегда определяю по данным. NVMe все стерпит.

* Без нужных ему данных glib определяет длину буфера для autodetect в 0. Ну, починил.

* Названия mime types в библиотеках немного расходятся. К счастью, авторы Evince это предусмотрели, и добавить нужный mime type было несложно.

Короче, все заработало, а бонусом я выяснил, что в диалоге открытия файлов в GTK не работали иконки, потому что им нужен mimetype. А я и не замечал.

Почему freedesktop не взяли эту либу за основу, я не понимаю. Ведь в OSS так много свободных рук.
6👍3🔥1
Мне тут в комментариях посоветовали вместо gnome files собрать https://wiki.lxde.org/ru/PCManFM #pcmanfm

Мне это показалось хорошим вариантом, часть LXDE, ни от чего не зависит(ну, почти), на вид выглядит не очень страшно.

Что характерно, поддержку gtk3 в нем запилило сообщество Arch, а, значит, проект пользуется некоторой популярностью, потому что так-то сообщество - жопа ленивая обычно.

Замечания по ходу процесса:

* libfm для сборки потребовало gtk-doc, причем практически неотключаемым образом.

Про свои муки с #docbook я уже как-то писал, но тут получилось, что просто так обойти эту зависимость не получается.

Небольшое лирическое отступление. Проекты на GNU #autohell требуют для построения configure наличие dev части некоторых зависимых пакетов, даже если ты потом не захочешь использовать этот пакет, и отключишь его через —disable-XXX.

Поэтому зависимость от gtk-doc я пока решил так - у меня корректно собирается и устанавливается часть gtk-doc, нужная для генерации autohell скриптов, а вот потом, если не позвать —disable-gtk-doc в configure, все будет взрываться самым неприятным образом. Я, конечно, нужный —disable- зову.

* libfm потребовала некую libmenu-cache, которая потребовала libfm. Я тут немного прифигел, но таки да:

https://github.com/lxde/menu-cache

"Since version 0.7.0 the Libmenu-cache requires Libfm-extra for the menu-cache-gen menu cache generation binary. Since Libfm depends on Libmenu-cache, there is some hint for bootstrapers how to build those libraries together: you need create Libfm-extra first, you can easily do this by passing '--with-extra-only' option to configure script and installing Libfm-extra."

С моей точки зрения:

* коллега нагадил посреди комнаты

* вместо того, чтобы тихонько прибраться, повесил табличку "я нагадил, обход тут"

"А что подумал по этому поводу Кролик, никто так и не узнал, потому что Кролик был очень воспитанный"

(нет, Кролик был в ахуе, и выпал в осадок так-то)

* К сожалению, посреди процесса сборки уже самого pcmanfm, я обнаружил, что оно таки непосредственно зависит от X11, и я не могу это собрать и использовать.

Сначала я решил, что ну и хер с ним, но потом внимательнее посмотрел на код, и понял, что могу изящно обойти эту зависимость от X, потому что она используется только если запустить этот FM в качестве X Desktop.

https://git.sr.ht/~pg/mix/tree/main/item/pkgs/bin/pcmanfm/mix.sh#L34

По сути, мне пришлось заменить один файлик размером 200К на несколько заглушек. Попрошу отметить, как я изящно расставил abort() в некоторых местах, чтобы быть уверенным, что мы не обсчитываем мусор. Все очень надежно!

Короче, оно даже запустилось, и даже заработало, с некоторыми глюками. Не работает прокрутка мышью, я это списываю на то, что никто и никогда этот код с Wayland не запускал, по понятным причинам. На вид чистенько, бедненько, все, как я люблю в софте.

Самое неприятное, конечно, в другом: #libmagic

Я успел прочитать часть кода, связанную с mime info, и с запуском приложений. Код рыхлый, неприятный, видно, что проект затащили грубой силой. Знаете, вот возникает момент, когда надо выделить функцию, а ты все равно в 10 местах вставляешь еще 1 if.

Поэтому за час у меня не получилось переделать всю эту машинерию на запуск xdg-open вместо своей таблицы отображения mime types на команду, а без этого у меня оно пока неюзабельно.

Пока отложил в сторону.
🔥8👍1
Я вчера написал, что не буду дочинивать #pcmanfm, но я был бы не я, если бы не взялся дочинить. Тревожный зуд что "что-то не работает" - штука такая. #debug

Прорвался сквозь сложносочиненный код для детектирования mime types, и выяснил нечто совершенно феерическое.

Если в одну программу слинковать lib/glib + lib/magic, то magic_buffer() начинает возвращать nullptr, а если без lib/glib - то "application/gzip" на данные для случайного .gz архива.

Это очень всрато, и, по сути, такое возможно только если с glib приезжают символы, которые оверрайдят какие-то weak символы в программе.

В процессе поиска я было отчаялся, но нашел флажок MAGIC_DEBUG, который выводил на экран запчасти от того, как работает #libmagic. Я там, почти случайно, понял, что:

* в libmagic есть правила на регулярках

* она их применяет линейным перебором, что, само по себе, пиздец

* libmagic ломается на первом же правиле с регулярками. Тут у меня, что называется, щелкнуло, и пазл сложился.
Вместе с glib приезжает libpcre, в составе которой есть библиотека libpcreposix.a, которая содержит в себе реализацию posix regex.x - regcomp/regexec/etc.

* (к слову, pcmanfm 4 раза дергает функцию для определения mime type для каждого файла, причем 2 раза из них реально считывает данные с диска)

Получалось так, что код собирался с определениями из musl regex.h, а линкер брал символы из pcre.

gdb) b regexec 
Breakpoint 1 at 0x2bf0cf: file src/pcreposix.c, line 328.
(gdb) b regcomp
Breakpoint 2 at 0x2bef33: file src/pcreposix.c, line 274.

Ни к чему хорошему это не приводило, в том числе, ломался и libmagic.

Я это починил, mime types заработали.

Ура? Пьем шампанское? Ага, конечно.

После пересборки world сломался браузер(напомню, что я использую epiphany).

Уже примерно понимая, в чем дело, я поставил breakpoint, и снял вот такой трейc:

#0  0x0000000008650e70 in regexec ()
#1 0x0000000007dd061b in optConfStartElem ()
#2 0x000000000857acb7 in doContent ()
#3 0x0000000008578394 in contentProcessor ()
#4 0x0000000008573ab6 in XML_ParseBuffer ()
#5 0x0000000007dcf4fb in parseOneConfigFile ()
#6 0x0000000007dcf33b in driParseConfigFiles ()
#7 0x0000000007d117a9 in loader_get_user_preferred_fd ()
#8 0x00000000068d74c9 in dri2_initialize_wayland ()
#9 0x00000000068d266a in dri2_initialize ()
#10 0x00000000068c4d99 in eglInitialize ()

Это, конечно, прекрасное. Это реальный случай про "два бага, которые отменяли друг друга".

Потому что, когда в glib была зависимость от pcreposix, ломался разбор конфига в mesa, и поэтому #zink (мой opengl driver) работал just as planned!

А когда я починил регулярки, конфиг начал обрабатываться правильно, и #zink начал глючить c новыми настройками!

Если вы когда-нибудь, зачем-то, хотели увидеть плачущего 40-летнего мужика, вам надо было быть вчера у меня дома.

Что с этим делать, пока непонятно.
😁22🤯5🔥4👍2😢1
У меня есть (короткий) список из нескольких задач, которые надо закрыть, прежде чем можно показать #stal/ix широкой общественности. #libmagic

Это задачи не про перфекционизм, а конкретные вещи, без которых "ничего работать не будет".

Как пример - дать возможность пользователю выбрать 3d драйвер из mesa. Пока у меня все заточено под мой setup из zink + radv, но там надо поддержать и более классическую схему с radeonsi, и intel, и software stack. Nouveau пока трогать не буду, подожду, пока они впилят наработки от open source nvidia.

На днях закрыл две задачи из списка - про размер курсора в gtk приложениях(он у меня был прибит гвоздями, а теперь может быть установлен через XCURSOR_SIZE), и про xdg-open.

Про xdg-open расскажу сегодня.

У вменяемого приложения под Linux есть два способа открыть какой-то внешний по отношению к себе файл:

* позвать портал через dbus.

* позвать command line тулзу xdg-open, передав ей путь к файлу или url.

Предполагается, что каждое DE будет предоставлять свой портал, или свой скрипт xdg-open(я тут немного упрощаю, для простоты объяснения).

К сожалению, in the wild я нашел только реализацию от freedesktop, и она настолько всратая, что у меня, при попытке это описать, остаются только матерные слова.

https://www.freedesktop.org/wiki/Software/xdg-utils/

(кстати, у невменяемых приложений есть и другие пути, например, KDE-шники любят долбиться в KParts, убил бы их за это, но это в следующей серии)

У меня какое-то время была заглушка для xdg-open, которая просто все открывала в браузере - https://github.com/pg83/ix/blob/99291c90267d7b690bc39fca7224c0a20b76334c/pkgs/bin/xdg/open/ix.sh#L8

Браузер умеет открывать почти все, и это решало 90% моих задач.

Но, кажется, людям такое отдавать несколько стыдно, но и насилолвать свой мозг через xdg-open от freedesktop мне не хотелось.

Поэтому я решил воспользоваться знанием того, какие у меня бинарники вообще бывают в дистрибутиве, и написал вот такой вот скрипт - https://github.com/pg83/ix/blob/main/pkgs/bin/xdg/open/scripts/xdg-open

Он определяет mime type переданного файла, и пытается для каждого известного типа выбрать наиболее подходящую программу из PATH. Ну и проваливается в браузер, если ничего не найдено(тут есть "мелкая" проблемка - а что, если xdg-open позвал браузер?).

Программы отсортированы по их известности. Потому что я предполагаю, что менее известная == более специализированная для пользователя, не просто же так он ее установил.

Так как в статически слинкованном дистрибутиве программы не могут появиться, кроме как из его пакетной базы, думаю, что такое решение вполне себе проживет год - другой.
🔥5👍1
commit -m "better"
Я вчера написал, что не буду дочинивать #pcmanfm, но я был бы не я, если бы не взялся дочинить. Тревожный зуд что "что-то не работает" - штука такая. #debug Прорвался сквозь сложносочиненный код для детектирования mime types, и выяснил нечто совершенно феерическое.…
https://www.opennet.ru/opennews/art.shtml?num=60611

Прикольная штука, определяет mime type быстрее и лучше, чем #libmagic.

Хотел заменить свою реализацию определения mime type в glib (да, она у меня кастомная - https://github.com/pg83/ix/blob/main/pkgs/lib/glib/ix/1.diff, поверх libmagic), потому что размер базы у нее всего 1 мегабайт, и работает быстрее.

Но:

* пока только на python

* onnx runtime - https://github.com/google/magika/blob/main/python/magika/magika.py#L24-L25

* https://github.com/google/magika/blob/main/python/magika/magika.py#L234 - фичи хотят для анализа целый файл, а это довольно много, если хочется всего лишь показать иконку в file manager.

Как говорится, будем наблюдать за проектом.
👍10🔥3🐳2🤔1👌1