LINUX.ORG.RU

Кеш для Desktop Entry

 , , ,


0

1

Здравствуйте! Возник такой вопрос (опять же, контекст - разработка легковесного DE). У меня сейчас при каждом открытии меню приложений читаются все *.desktop файлы из /usr/share/applications и ~/.local/share/applications (я знаю, что это не совсем правильно, и на самом деле надо проходиться по всем директориям из $XDG_DATA_DIRS, но пока что так). Я написал с нуля класс, который читает и парсит Desktop Entry (можно было бы использовать QSettings, как я собственно и делал раньше, но формат *.ini не предполагает перечислений через точки с запятыми, а именно это представляет собой параметр Categories, поэтому раньше не было возможности сделать меню по категориям). Но как-то не очень легковесно это, по-моему, каждый раз читать, вполне возможно, за сотню с лишним файлов с диска. Я где-то видел, что для этого используется т.н. menu-cache. Вопросов встает несколько:

  • Стоит ли пользоваться этим menu-cache? Т.е., насколько я понял, создается один файл, в котором закешированы основные параметры из каждого Desktop Entry, и апплет читает уже только его, чтобы снизить нагрузку на диск. Хотя может я и неправильно понял?

  • Является ли он стандартом / есть ли подобный стандарт от тех же Freedesktop, например?

  • А как этот кеш обновляется? Вот я изменил как-нибудь, допустим, файл *.desktop в /usr/share/applicaitons. И что, при добавлении/изменении/удалении надо каждый раз прописывать какую-нибудь команду для обновления кеша? А как сделать, чтобы пакетный мендежер автоматически это делал? Например, в Debian, насколько понимаю, так это и происходит. Мы же, когда ставим пакет, пакетный менеджер этот кеш меню автоматически обновляет.

Или не стоит это все того, и лучше оставить как есть?

UPD: Либо есть еще вариант. Один раз при запуске прочитать все файлы. Допустим, повесить QFileSystemWatcher на ту же /usr/share/applications и при изменении каком-либо обновлять список приложений, чтобы не делать это при каждом открытии меню приложения.

Заранее спасибо.



Последнее исправление: thm (всего исправлений: 2)

можно было бы использовать QSettings, как я собственно и делал раньше, но формат *.ini не предполагает

QSettings::registerFormat и любой парсер на твой вкус, так-то…

aol ★★★★★
()
Ответ на: комментарий от aol

QSettings::registerFormat

а чем это лучше? все равно же, получается, пишем свои методы парсинга файла (ну, судя по вот этому куску из доков):

bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);

int main(int argc, char *argv[])
{
    const QSettings::Format XmlFormat =
            QSettings::registerFormat("xml", readXmlFile, writeXmlFile);

    QSettings settings(XmlFormat, QSettings::UserScope, "MySoft",
                       "Star Runner");

    ...
}

разве что файл вручную не открываем, а остальное, по факту, то же самое.

но этот кусок кода все равно нужен в разных местах несколько раз, поэтому правильным решением его было, считаю, вынести в отдельную библиотеку

thm
() автор топика
Ответ на: комментарий от thm

тезис-то был не про лучше/хуже, а про то, что кусеттингз - только ини. но это не так )

ну, а по теме ОП, кэш - дело хорошее, в любом случае. и скучать не даёт, опять же - there are two problems in the computer science: cache invalidation, naming things and off-by-one errors. 🤭

aol ★★★★★
()
Ответ на: комментарий от aol

кусеттингз - только ини. но это не так )

Понял, спасибо

скучать не даёт

А этот вариант насколько адекватный: Один раз при запуске прочитать все файлы. Допустим, повесить QFileSystemWatcher на ту же /usr/share/applications и при изменении каком-либо обновлять список приложений, чтобы не делать это при каждом открытии меню приложения?

thm
() автор топика
Ответ на: комментарий от thm

на мой неискушенный взгляд, событие по изменению состава десктоп файлов настолько маловероятное, что вешать на каталог QFileSystemWatcher выглядит каким-то оверкиллом. Почему бы эту заботу не сгрузить на пакетный менеджер?

aol ★★★★★
()
Ответ на: комментарий от aol

Ну, вот как раз я потому и спрашивал про то, является ли menu-cache стандартом. Т.е. можно ли быть уверенным, что если в системе стоит какой-то пакет X, который отвечает за кеш меню, оно будет всегда автоматически обновляться пакетным мендежером при установке пакета, который кладет в ту же /usr/share/applications свой Desktop Entry?

thm
() автор топика
Ответ на: комментарий от thm

… а есть еще умельцы превратить любую систему в слаку… их тоже будем учитывать или как-то сами пусть выгребают?

aol ★★★★★
()
Ответ на: комментарий от aol

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

cobold ★★★★★
()

Мысли в слух

Тут по моему надо проявлять эту как её, изобретательность или типа того, ибо комфорт работы с DE завист от мелочей типа «тупит меню» и если твоя DE будет прям вся такая офигенная, но тупит меню, всем будет пофиг на офигеность, будет просто «тупить меню», а мол это та DE где тупит меню :), а не делать всё влоб, или так, или эдак.

  • Хранить у себя
    • количество файлов в каталогах $XDG_DATA_DIRS
    • время последней модификации файлов в $XDG_DATA_DIRS
    • При открытии меню, сначала смотреть
      • У списка учтённых файлов что-то изменилось?
        • Если да то пречитать только то что изменилось
        • Если нет то количество файлов изменилось?
          • Если да то прочитать только новое
          • Если нет то ничего не делать и показать уже у себя закешированное меню

Может ещё что-то вроде этого или типа того добавить, любая операция с ФС это тяжесть, тебе так или иначе нужно уметь прочитать всё в $XDG_DATA_DIRS как минимум при первом запуске твоего DE, а затем по мере возможности не перечитывать там всё, а перечитывать только то что изменилось и вот тут уже проявляй смекалку. В любом случае в самом меню можно добавить кнопочку «обновить» для принудительного обхода, мало ли чего.

Чисто технически, у тебя тучка мелких файлов которые, могут читаться каждый раз когда пользователь тыкает в кнопку Super на клавиатуре. А если он будет на неё тык-тык-тык-тык-тык это же бенчмарк ФС практически :) Поэтому ещё стоит сохранять время в течении которого не будет проверятся ни ФС ни метаданные о том проверять ли ФС (время изменения файлов и их количество в каталогах), ибо зачем?

Я подозреваю что libmenu-cache.so что-то в эту сторону делает. Но это не точно. Так или иначе кешировать данные из пачки ini файлов и проверять потом анунали перечитывать ты и сам сможешь, без внешних зависимостей.

Допустим пользователь псих и у него 1000 файлов запуска в ~/.usr/share/applications/ и он долбит по Super 2 раза в секунду. Оно должно отображать меню, два раза в секунду. Возможно с пролагом в первых раз, хотя и это лучше обойти запустив обход в процессе начала старта, а лучше параллельно ему в share memory какойнито воть.

Короче тут упарываться можно бесконечно, хехе. Всё я закончил.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от aol

ну, я же могу этот пакет, который отвечает за кеш меню, просто зависимостью сделать :)

в Арч вики пишут, что вот типа есть пакет desktop-file-utils, который предоставляет утилиты вроде desktop-file-install и update-desktop-database:

Use desktop-file-install(1) to install desktop file into target directory. For example: $ desktop-file-install --dir=$HOME/.local/share/applications ~/app.desktop

Usually, desktop entry changes are automatically picked up by desktop environments. If this is not the case, and you want to forcefully update the desktop entries defined in ~/.local/share/applications, run the following command: $ update-desktop-database ~/.local/share/applications

thm
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

давным-давно, когда я пользовался гномом, у меня была ровно такая же ситуация. кладу *.desktop файл, а ярлыка нет. Приходилось потыкать раз 10 меню приложений и сколько-то времени подождать, пока оно там не появлялось. собственно, не хотелось бы, чтобы так было :) да, спасибо за идеи, подумаю, как это реализовать, чтобы проверять, обновилось ли что и, если да, перечитывать

thm
() автор топика
Ответ на: комментарий от thm

ну, я же могу … просто … :)

ты недооцениваешь способности персонажей из чего угодно сделать слаку )

в целом, я бы придерживался общепринятых практик. можно в кедах подглядеть, раз уж ты на куте пишешь…

aol ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

хотя кстати раньше многие пытались (еще во времена XP где-то) делать что-то наподобие DE под винду :) были и панели отдельные, типа ObjectBar, можно было винду превратить в Mac OS X (и не так колхозно, как это обычно вот эти Transformer Pack’и делали, что остается меню спуск виндовое, а прям реалистично) даже был какой-то порт KDE под винду. да и щас подобным занимаются. dwm-win32, например )

но это мы уже от темы отошли ахах )

thm
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Есть еще вопросы по поводу $XDG_DATA_DIRS. Во-первых, эта переменная далеко не везде определена. В Арче у меня например не определена по дефолту. В минте на виртуалке проверил есть. Но это не самая большая проблема (в доках freedesktop написано по дефолту, если не определена, брать ее за /usr/local/share/:/usr/share/).

Что действительно проблема, так это то, что не ясен приоритет. В доках четко написано, что локальные Desktop Entry (~/.local/share/applications) стоят выше, чем глобальные (/usr/share/applications). Т.е. если есть два Desktop Entry с одинаковым именем файла, должен быть показан тот, что лежит в локальной директории. Окей.

Но локальная директория, внезапно, вообще не определена в $XDG_DATA_DIRS. там ее просто нет. т.е. ее надо брать из воздуха? наверняка же, ~/.local/share/applications - не единственный вариант.

Далее, а каков приоритет остальных директорий, которые в $XDG_DATA_DIRS прописаны? я понимаю, что вероятность того, что директория applications будет где-то, кроме /usr/share, так еще и что там имена файлов совпадут - околонулевая, но все же. как быть? кто важнее? /usr/share или какая-то другая директория, которая прописана в $XDG_DATA_DIRS? от чего это зависит?

thm
() автор топика
Ответ на: комментарий от thm

У меня вот так

dron@gnu:~$ echo $XDG_DATA_DIRS
/usr/share/gnome:/usr/local/share/:/usr/share/
dron@gnu:~$ 

С удивлением вижу что гном себе отдельно сделал, ну да ладно. Сразу видно что тут нет /home/$USER/.local/share и это надо на уровне приложения добавлять автоматом (если каталог этот вообще есть)

Короче, мне кажется нужно рассматривать $XDG_DATA_DIRS как скорее дополнение, юзер может это переопределить. Бери сам то откуда оно предполагается (если оно есть), и дополнительно из $XDG_DATA_DIRS (исключая дубли). А так, всё всегда в /usr/share,/usr/local/share и ~/.local/share ну как минимум это. Если есть где то ещё следуя $XDG_DATA_DIRS то ещё и от туда, если там что-то новенькое прописано. А если переменной оружения нет то ты просто надеишься что оно лежит в трёх местах что выше я сказал, что найдёшь, то и найдёшь. А если ничего нет, ну значит нет.

Типа того, но я не спец, я просто мыслевслухаю

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

А так, всё всегда в /usr/share,/usr/local/share и ~/.local/share ну как минимум это.

Ну, это отлично, вот только что делать, если в /usr/share/applications и /usr/local/share/applications окажется Desktop Entry с одним и тем же именем файла? Что делать, если окажется в глобальном и локальном - ясно, написал выше, в доках все написано. А если в двух глобальных директориях? Или такого быть не должно и предусматривать такое не надо?

Сразу видно что тут нет /home/$USER/.local/share и это надо на уровне приложения добавлять автоматом (если каталог этот вообще есть)

Вот и я про то же, что его в $XDG_DATA_DIRS нет, хотя он часто достаточно используется. Ну т.е. получается, что вот эту директорию ~/.local/share/applications надо просто захардкодить

thm
() автор топика
Последнее исправление: thm (всего исправлений: 2)
Ответ на: комментарий от thm

Что действительно проблема, так это то, что не ясен приоритет.

У всего что в пути есть local приоритет должен быть выше, ну типа вот такой пример

  • Самый высокий приоритет ~/.local/share
  • Чуть ниже /usr/local/share
  • Самый низкий (система) /usr/share

Суть в том что то что переопределено имеет выше приоритет чем то что уже есть.

  • Типа хочу для всех то в /usr/share
  • Хочу для всех переопределить то /usr/local/share
  • Хочу для себя переопределить всё что уже есть, включая что до меня уже переопределили то ~/.local/share
LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

ок, примерно понятно, но понятно, когда директории три и заранее известных. а если туда что-то юзер в $XDG_DATA_DIRS допишет, и в этом чем-то, что ничего не переопределяет (local в пути нет) окажется файл с таким же именем, что и в той же /usr/share/applications, то что тогда делать? вероятность этого, конечно, еще ниже, чем что даже в /usr/local/share/applications что-то окажется, но тем не менее, такое же возможно

или таки, в двух глобальных директориях, которые ничего не переопределяют, повторяющихся имен файлов быть не может?

thm
() автор топика
Последнее исправление: thm (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

так, документация сомнения развеяла:

If multiple files have the same desktop file ID, the first one in the $XDG_DATA_DIRS precedence order is used.

т.е. выходит, что приоритет - тот, который задан в переменной $XDG_DATA_DIRS. ну, это все сильно облегчает. (+ ессно в самое начало добавляем ~/.local/share/applications)

thm
() автор топика
Последнее исправление: thm (всего исправлений: 2)

Не трахай моск, у тебя оно все в page cache и inode cache ляжет после первого прочтения и не будет с диска подниматься

no-dashi-v2 ★★★
()
Ответ на: комментарий от no-dashi-v2

но получается, имея кеш, можно и первого прочтения избежать ) сравнить условно timestamp изменения каждой директории из $XDG_DATA_DIRS с timestamp’ом, который записан в файле кеша. и если где-то среди файлов он новее, то этот файл перечитать и кеш обновить

thm
() автор топика
Ответ на: комментарий от thm

А данные в памяти сами появятся? Или ты все же прочитаешь какой-то файл на диске, перед этим все равно обойдя все файлы.

Тут какая-то экономия на спичках.

masa
()
Ответ на: комментарий от masa

перед этим все равно обойдя все файлы

почему обойдя все файлы? я прочитаю свой кеш меню и если timestamp изменения кеша >= timestamp изменения директории с файлами *.desktop самой по себе (для этого же не надо проходиться по всем файлам. изменили один файл => изменили всю директорию), то просто воспользуюсь кешем, в котором заранее записаны нужные мне ключи из Desktop Entry. А если таки изменилось что-то, то я буду заново читать с диска только те файлы, timestamp изменения которых новее timestamp’а в конфиге

thm
() автор топика
Последнее исправление: thm (всего исправлений: 2)
Ответ на: комментарий от masa

Тут какая-то экономия на спичках.

Вот потому и спрашиваю, стоит это все того, или ‘и так сойдет’ :)

UPD: В принципе, ничего не мешает выпустить в релиз то, что уже проверено временем, потом провести дополнительные тесты и уже решить, надо оно или нет. Но я просто хотел следующий релиз выпустить уже 1.0.0. изменений столько, что катит на следующую major версию (после 0.7.1). т.е., раз 1.0, то принято считать, что каких-то критических, глобальных проблем быть не должно :)

thm
() автор топика
Последнее исправление: thm (всего исправлений: 2)
Ответ на: комментарий от masa

да, этот момент я как-то не учел

thm
() автор топика
Ответ на: комментарий от masa

При изменении файла (не создании-переименовании а именно записи в существующий файл) директория не меняет дату, внезапно. Никогда не меняла.

no-dashi-v2 ★★★
()
Ответ на: комментарий от no-dashi-v2

не создании-переименовании

а-а. ну тогда, затея вообще фиговая, получается

thm
() автор топика
Ответ на: комментарий от thm

Есть еще вопросы по поводу $XDG_DATA_DIRS.
Что действительно проблема, так это то, что не ясен приоритет.
Но локальная директория, внезапно, вообще не определена в $XDG_DATA_DIRS. там ее просто нет. т.е. ее надо брать из воздуха?
вот только что делать, если в /usr/share/applications и /usr/local/share/applications окажется Desktop Entry с одним и тем же именем файла?

/home/$USER/.local/share

его в $XDG_DATA_DIRS нет, хотя он часто достаточно используется.

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

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

я оттуда и пришел и сначала невнимательно прочитал + потом написал

так, документация сомнения развеяла: If multiple files have the same desktop file ID, the first one in the $XDG_DATA_DIRS precedence order is used.

про ~/.local/share уже тоже понял, она определена в $XDG_DATA_HOME

thm
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.