LINUX.ORG.RU

«Правильный» способ определения .desktop-файла для запущенного приложения

 , ,


0

2

Есть запущенное произвольное X-овое приложение.

Необходимо найти (если есть) с каким *.desktop-файлом оно ассоциировано.

Известны его PID, его XID.

Проблемы:

1. Имя окна (и даже имя приложения с которым связано окно) != Название программы. Ну т.е. например имя браузера сейчас - «Добавить сообщение - Chromium»;

2. procfs почему-то отображает обрезанные имена. Собственно,

[ntfs@ntfs-a320mh 12799]$ ps -p 12799 -o comm=
telegram-deskto
[ntfs@ntfs-a320mh 12799]$ 
последней буквы нет;

3. Альтернативно-одаренные называют *.desktop-файлы нестандартными именами, которые больше нигде не светятся. Вот например вышеупомянутый телеграмм у нас - org.telegram.desktop.desktop;

4. В системе ПЯТЬ разных имен для одной и той же сущности: *.desktop - org.telegram.desktop, WM_NAME - Telegram (1597), XAPP_NAME - TelegramDesktop, procfs comm - telegram-deskto, procfs cmdline - telegram-desktop--

Благодарю.

★★★★★
Ответ на: комментарий от anonymous

Правильный способ – использовать готовое DE а не пыжиться сделать свой велосипед.

Еще раз перечитай тему. Внимательно. Там задан очень простой вопрос.

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

Ключи запуска обычно смотрят в –help или man , само приложение с десктоп файлом никак не связано. Там лишь команда его запустившая, обратно отследить можно лишь при полном логировании. Можно парсить состав установочного пакета этого приложения на наличие разных десктоп файлов . Или директорию хранения десктоп файлов и наличие в их командах приложения. Для чего именно ваша хотелка должна применяться конкретнее

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

Будешь тупить как в Что за формат IconPixmap, или вопрос любителям обмазываться X и d-bus ?

Конечно буду. Был бы умным - не спрашивал бы, и уж тем более не вел бы с тобой дискуссию.

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

Ключи запуска обычно смотрят в –help или man , само приложение с десктоп файлом никак не связано. Там лишь команда его запустившая, обратно отследить можно лишь при полном логировании. Можно парсить состав установочного пакета этого приложения на наличие разных десктоп файлов . Или директорию хранения десктоп файлов и наличие в их командах приложения. Для чего именно ваша хотелка должна применяться конкретнее

Для избавления от костылей в реализации панели задач. То есть для оптимизации.

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

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

Тут уже только парсить /usr/share/applications на предмет совпадения с индефикатором окна , связь с десктоп файлом иначе ника не получите

wmctrl -lx и подобное

Можете глянуть как организовано подобное в xatk , там питон и кода немного

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

Нужно гренпуть корень на предмет строки запуска приложения. Из всех совпадений выбрать файлы .desktop. Далее использовать дедукцию.

В этом и проблема, что «дедукция», а не «унификация».

Да, сейчас так и делаю, читаю все десктоп-файлы в ассоциативный массив с Exec в качестве индекса. Затем читаю весь этот набор свойственный конкретному процессу, и ищу совпадения. Но это не метод, это дроч.

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

Потому что ассоциативный массив излишен там, где достаточно grep, awk, sort, uniq и прочего. Конкретно, например для telegram-desktop

sudo grep --include=\*\.desktop -rnw / -e "telegram-desktop" 2>/dev/null

достаточно.

Что значит, начиная от корня и везде (где получится), файлы с расширением .desktop, проверить на наличие строки telegram-desktop (регулярного выражения), и если есть совпадение – напечатать путь к файлу, номер строки и саму строку целиком.

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

Подожди. Нет никакого «telegram-desktop» пока. Есть PID 1319. Ну хорошо, XID 180321 есть.

comm у этого PID: telegram-deskto, как написали выше из-за ограничения на длину

Имя X-окна 180321 - Telegram (112)

Имя приложения, запустившего окно 180321 - TelegramDesktop

Командная строка для запуска согласно procfs - telegram-desktop--

[ntfs@ntfs-a320mh applications]$ sudo grep --include=\*\.desktop -rnw /usr/share/applications/ -e "pcmanfm" 2>/dev/null
/usr/share/applications/pcmanfm.desktop:148:Exec=pcmanfm %U
/usr/share/applications/pcmanfm-desktop-pref.desktop:103:Exec=pcmanfm --desktop-pref
[ntfs@ntfs-a320mh applications]$ 

Вот это как раз то, о чем я говорю, имея в виду отсутствие унификации.

windows10 ★★★★★
() автор топика

В гном щели можно через Looking Glass посмотреть (Alt+F2 -> lg):

  1. Тыкаем вкладку windows,
  2. Выбираем нужное,
  3. тыкаем в аттрибут AppInfo,
  4. смотрим filename.

Очевидно, можно как-то и программно, через extensions javascript api.

snizovtsev ★★★★★
()
Последнее исправление: snizovtsev (всего исправлений: 1)

Нельзя определить, запущено приложение с десктоп-файла или иначе. Оно может быть запущено из ФМ, скриптом-оберткой, просто из терминала, различными вариациями «menu» (dmenu, меню WM и т.д.), где просто прописана команда.

Даже если смотреть родительский процесс. Например огнелис и тайликс запущены из меню xfce, т.е. на самом деле из десктоп-файлов, причем тайликс не прописан явно, а запускается, как терминал по-умолчанию.

$ (gps firefox).CommandLine
/usr/lib/firefox/firefox

$ (gps firefox).Parent.CommandLine
xfce4-panel

$ (gps tilix).CommandLine
tilix

$ (gps tilix).Parent.CommandLine
/usr/lib/systemd/systemd --switched-root --system --deserialize=43
dmitry237 ★★★★
()
Ответ на: комментарий от dmitry237

Да, я так понимаю загрузка desktop происходит вообще после запуска процесса, а не перед. Т.е. если запустить desktop, который лежит вне системных директорий (через какой-нибудь dex), то гном попытается заматчить его на системный desktop, и если найдёт – загрузит инфу оттуда (иконку, меню), а не из оригинального «ярлыка». По сути это вообще не ярлык.

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

Командная строка в procfs отличается от строки в оболочке (или desktop-файле), тем, что вся возня с аргументами уже завершена и они переданы в готовом виде приложению.

В принципе и этот вопрос вполне решаемый

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

Ну да, собственно,

cat /proc/673603/cmdline | sed -e "s/\x00/ /g"; echo
/usr/bin/telegram-desktop -- 

Просто в procfs разделение идёт именно как в

void
main(int argc, char* argv[]) {}

То есть через ноль. И он не печатается при cat. Точнее, это непечатаемый символ.

Полный путь и -- скорее всего добавляется уже после. Не так как в файле. Поэтому следует их отрезать. Ну я в принципе всё вообще обрезал

basename $(cat /proc/673603/cmdline | sed -e "s/\x00/ /g" | awk '{ print $1 }')
telegram-desktop
thegoldone ★★
()
Ответ на: комментарий от snizovtsev

В гноме все годаздо проще: щель кидает процесс, запущенный из .desktop файла и все его дочерние процессы в отдельную цгруппу, имя которой – прозводное от имени десктоп файла:

$ cat /proc/168157/cgroup  
0::/user.slice/user-1000.slice/user@1000.service/app.slice/app-gnome-org.gnome.Evince-168157.scope

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

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

То есть даже графический сервер запустивший приложение, не имеет возможности узнать его имя. Ну и бардак.

Это лютое легаси. Графический сервер не запускает приложения, это клиенты подключаются к серверу, и предоставляют тот минимум информации, который посчитают нужным. При этом даже нет гарантии, что клиент и сервер работают на одной машине, и данные клиента в принципе будут достпны где-либо еще. Т.е не факт, что даже если приложение сообщит тебе корректное со своей точки зрения имя desktop-файла, этот файл найдётся на хост-системе и будет реально соответствовать этому приложению. Бред? Да, но кто-то до сих пор этим пользуется.

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

Да, я так понимаю загрузка desktop происходит вообще после запуска процесса, а не перед.

Загрузка desktop приводит к запуску процесса. Просто не тред, а перепись неучей и говнокодеров.

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

Загрузка desktop приводит к запуску процесса.

Разговор не про сам десктоп-файл, а про родительский процесс. Например mousepad из меню крысы запускает xfce4-panel, а точно такой же десктоп-файл c рабочего стола запускает Thunar --daemon, в остальных случаях, например из терминала, этот же десктоп-файл запускает /usr/lib/systemd/systemd --switched-root --system --deserialize=43

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

Еще раз перечитай тему. Внимательно. Там задан очень простой вопрос.

Просто вопрос некорректный. Не desktop принадлежит приложению, а наоборот. У меня, например, есть desktop-файл(для я.браузера), который вообще ведет на мой самописный sh-скрипт, который делает ещё кучу действий(в частности переключает workspace в WM, чтобы при открытии ссылки переходить в браузер). И вот какому приложению будет такой desktop-файл соответствовать? Также вполне нормальна ситуация, когда у приложения вообще не будет desktop-файла и его будут запускать из терминала руками или вообще systemd юнитом.

Loki13 ★★★★★
()
Последнее исправление: Loki13 (всего исправлений: 1)
Ответ на: комментарий от anonymous

точно такой же десктоп-файл? Вот прям до байта такой же?

абсолютно, просто скопировал:

$ md5sum /usr/share/applications/org.xfce.mousepad.desktop         
506995aefd73a8185f89679f381f1a96  /usr/share/applications/org.xfce.mousepad.desktop

$ cp /usr/share/applications/org.xfce.mousepad.desktop ./Desktop  

$ md5sum ./Desktop/org.xfce.mousepad.desktop                    
506995aefd73a8185f89679f381f1a96  ./Desktop/org.xfce.mousepad.desktop
dmitry237 ★★★★
()
Последнее исправление: dmitry237 (всего исправлений: 1)

В общем смотрите какой юзкейс.

Пишу док.

Загвоздка дока и его отличие от таскбара в том, что здесь элементы запущенных и незапущенных программ - совмещены в один. То есть у нас есть условный каталог с ярлыками, мы его прочитали и вывели, все нормально.

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

После чего закрепленные программы, как запущенные, так и не запущенные - можно открепить. То есть просто удалить условный ярлык с определенной директории.

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

Далее. У окна есть понятие иконки, это pixbuf. Этот pixbuf волею отсутствия четких и твердых гайдлайнов - может различаться с системной темой, а то и вообще отображать «fallback» в то время как в системной теме есть соответствующая иконка, т.е. читать информацию с Х11 - не вариант. Собственно как и имена, они устанавливаются не стандартно, а могут не устанавливаться вообще, равно как устанавливаться в произвольном порядке.

Я искал правильный способ найти соответствующий *.desktop-файл для запущенного приложения, если таковые существуют (как файл так и способ). Но похоже такого способа нет.

Проблему я решил методом парсинга, if\then'ов и прочего дроча, благо PHP в этом плане позволяет разгуляться.

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

У окна есть понятие иконки, это pixbuf. Этот pixbuf волею отсутствия четких и твердых гайдлайнов

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

Есть и ~/.local/share.

И это не секретная информация. Гугл: linux application icons location. Там все необходимые подробности.

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

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

В этом и проблема, что невозможно достоверно получить имя приложения.

Программа начинается с поиска открытых окон в графическом сервере через иксовый API. Каждое из этих окон имеет в параметрах «иконку», «имя», «xid». Поле «имя» содержит бардак, начиная от пустого и заканчивая титулом, например у окна где я сейчас пишу имя «Добавить сообщение». Ладно, с помощью того же API можно узнать PID приложения открывшего окно.

По PID'у можно получить имя, но имен несколько, и они могут быть разными. Я уже привел варианты имен для телеграмма например.

И это не секретная информация. Гугл: linux application icons location

Нет. Pixbuf делает само приложение. Оно может брать как оттуда иконки, так и от себя иконки, так и рисовать их вручную. Есть тема где вайберовских иконок нет, но иконки рисуются. Далее, когда в телегу приходят сообщения, иконка выглядит как иконка телеги с красным кружочком, посреди которого нарисована цифра количества непрочитанных сообщений.

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

По PID’у можно получить имя, но имен несколько, и они могут быть разными. Я уже привел варианты имен для телеграмма например.

Имя исполняемого файла без /usr/bin и прочего. Например – firefox.

И соотв.

/usr/share/icons/hicolor/scalable/apps/firefox.svg 
/usr/share/icons/hicolor/64x64/apps/firefox.png 

и так далее.

Нет. Pixbuf делает само приложение.

И при чём тут тогда *.desktop файл?

Нет. Pixbuf делает само приложение.

А ещё оно может не использовать ни GTK ни KDE а собственный механизм. И не будет способа получить его через библиотечные вызовы, если таковое вообще возможно.

И что?

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

Имя исполняемого файла без /usr/bin и прочего. Например – firefox.

А теперь то же самое для lxrandr, gnome-disk-utility, звукового микшера, приложений с разными ключами (к примеру pcmanfm) и еще примерно половины типичного десктопного набора программ, где иконки различаются с названиями =)

И при чём тут тогда *.desktop файл?

При том что именно с него можно вытащить данные установленной программы для дальнейшего отображения. Если он есть конечно.

А ещё оно может не использовать ни GTK ни KDE а собственный механизм. И не будет способа получить его через библиотечные вызовы, если таковое вообще возможно.

Это фишка графического сервера, т.е. запустившись, оно обязано создать окно с необходимыми параметрами. Или NULL если позволено. Кто в конечном итоге создаст окно, программа или программа через GTK не имеет значения. Чтобы узнать какие окна (не приложения, а окна) работают в системе - их надо перебрать.

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

Вот можно было такой пост написать, концентрированный. А то файлы какие-то, процессы

Не совсем понимаю к чему это было написано. Еще один свидетель «всьодолжнобытьнасях» что ли?

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

А теперь то же самое для lxrandr, gnome-disk-utility, звукового микшера […]

Ну так если способ 1 не сработал, то способ 2. И так далее. В самом конце показ какой-то системной иконки. Если ничего не сработает.

При том что именно с него можно вытащить данные установленной программы для дальнейшего отображения. Если он есть конечно.

Там вполне может не быть информации об изображении.

Всегда можно найти исполняемый файл. По нему найти пакет. Получить список файлов этого пакета. Найти там изображения. Не универсальный подход. Для каждого пакетного менеджера свой.

Простенький шелл.

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

Ну так если способ 1 не сработал, то способ 2. И так далее. В самом конце показ какой-то системной иконки. Если ничего не сработает.

Вот. Поэтому вопрос изначально встал о ПРАВИЛЬНОМ способе.

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

windows10 ★★★★★
() автор топика