In the Unity desktop, when I start в GUI application, its icon appears in the launcher (if it isn't already there).
Now when I right-click this icon, I either get the option Lock to Launcher or Unlock from Launcher, depending on whether the application is already locked to the launcher or not.
My question is:
What happens under the hood, when I click one of those two options if не .desktop
file exists?
Хан it automatically сочтите тебе простым .desktop
поля if it can't find one, under which conditions май that happen, and where do the pinned launcher статьи get saved?
Не уверенный, если этот ответ глубоко достаточно находится под "капотом", но это - то, что происходит:
Можно получить текущее содержание Средства запуска Единицы командой:
gsettings get com.canonical.Unity.Launcher favorites
Это произведет список, будучи похож:
['application://extras-qlequicklisteditor.desktop', 'application://gedit.desktop', 'application://gnome-terminal.desktop', 'application://nautilus.desktop', 'application://firefox.desktop', 'application://thunderbird.desktop', 'application://gnome-screenshot.desktop', 'application://dconf-editor.desktop', 'application://virtualbox.desktop', 'application://gnome-tweak-tool.desktop', 'unity://running-apps', 'unity://devices', 'unity://expo-icon']
Упоминания в списке, очевидно, основаны на названиях соответствия .desktop
файлы.
Теперь то, когда Вы запускаете приложение GUI, когда Вы щелкаете правой кнопкой по его значку в средстве запуска и выбираете Lock to Launcher, в настоящее время выбираемый объект добавляется к списку, в то время как Разблокировали от Средства запуска, удалит объект из списка.
Пере - чтение Вашего (первого) комментария ниже Вашего вопроса: как упомянуто, можно получить текущие объекты Средства запуска командой:
gsettings get com.canonical.Unity.Launcher favorites
и набор возможный измененный список командой:
gsettings set com.canonical.Unity.Launcher favorites "[item1, item2, etc]"
Можно затем, конечно, отредактировать содержание Средства запуска Единицы программно, как сделан здесь.
Если Вы запускаете приложение GUI без существующего .desktop
файл, Единица создает основной локально (в ~/.local/share/applications
), названный в честь исполняемого файла (application.desktop
). В Exec=
строка, Вы найдете команду, которую Вы выполнили, для вызова приложения.
Если Вы изучили бы a .desktop
файл, созданный этот путь, это включает строку:
X-UnityGenerated=true
Как упомянуто @muru (Спасибо!), в некоторых (исключительный, поскольку это кажется) ситуации, Единица не успешно выполняется для создания "отсутствия" .desktop
файл исполняемого файла. Единственный пример, который я мог найти однако, был в случае окон Tkinter, которые принадлежат pid 0
в выводе wmctrl -lp
.
То, что происходит, когда Вы нажимаете опцию Lock To Launcher, то, что Единица изменится конкретный dconf
схема для избранного средства запуска и вызова несколько dbus
методы. Ключ для программистов и разработчиков приложений является изменением в dconf
схема. (Ответ Jacob полагается gsettings
, однако идея является по существу тем же как gsettings
просто фронтэнд с проверкой работоспособности для dconf
). Здесь, я просто хочу представить несколько сделанных наблюдений.
Примечание стороны: здесь, я тестирую все с пользовательским приложением Python, которое имеет нет .desktop
файл
Выполнение dconf watch /
покажет, что это - то, что изменяется:
$ dconf watch / # Lock to launcher
/com/canonical/unity/launcher/favorites
['application://gnome-terminal.desktop', 'application://firefox.desktop', 'application://gedit.desktop', 'application://sakura.desktop', 'application://mplab.desktop', 'unity://running-apps', 'application://pyqt_clock_py.desktop', 'unity://devices']
# Unlock from launcher
/com/canonical/unity/launcher/favorites
['application://gnome-terminal.desktop', 'application://firefox.desktop', 'application://gedit.desktop', 'application://sakura.desktop', 'application://mplab.desktop', 'unity://running-apps', 'unity://devices']
Первоначально, существует проверка действительно ли .desktop
файл существует для приложения. Если файл существует - хороший. Если не - Единица будет проблема a dbus
звоните в org.ayatana.bamf.control.CreateLocalDesktopFile
метод на org.ayatana.bamf
сервис. Это может использоваться для автоматизации .desktop
создание файла. Хотя, это выполняет не в разоблачении dbus-monitor
вывод, я полагаю, что это - один из методов, которые могут быть используемой Единицей.
Вот маленькая демонстрация:
# start custom app in background, app appears on the launcher
$> python /home/xieerqi/bin/python/pyqt_clock.py &
[1] 16768
# confirm that there is no .desktop file for that app
$> qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.RunningApplicationsDesktopFiles
/usr/share/applications/compiz.desktop
/usr/share/applications/firefox.desktop
/usr/share/applications/x-terminal-emulator.desktop
$> ls .local/share/applications/pyqt_clock_py.desktop
ls: cannot access .local/share/applications/pyqt_clock_py.desktop: No such file or directory
# I use custom function to find list of running apps by their dbus path
$> typeset -f running_apps
running_apps() {
qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.RunningApplications | xargs -I {} bash -c "echo {}; qdbus org.ayatana.bamf {} org.ayatana.bamf.view.Name"
}
$> running_apps
/org/ayatana/bamf/application/0x146bb90
Clock
/org/ayatana/bamf/application/1932146384 # that's what we want
Firefox Web Browser
/org/ayatana/bamf/application/1060483892
MY CUSTOM TERMINAL
/org/ayatana/bamf/application/885622223
Compiz
/org/ayatana/bamf/application/0x146b8f0
# Use the dbus method to create desktop file
$> qdbus org.ayatana.bamf /org/ayatana/bamf/control \
> org.ayatana.bamf.control.CreateLocalDesktopFile /org/ayatana/bamf/application/0x146bb90
# Verify its creation
$> ls .local/share/applications/pyqt*
.local/share/applications/pyqt_clock_py.desktop
# This doesn't however pin the program to launcher
# Different call to dbus will be issued
$ gsettings get com.canonical.Unity.Launcher favorites
['application://gnome-terminal.desktop', 'application://firefox.desktop', 'application://gedit.desktop', 'application://sakura.desktop', 'application://mplab.desktop', 'unity://running-apps', 'unity://devices']
Существует другой dbus метод, который уничтожает файл:
Я выполнил блокировку и разблокирование действия с dbus-monitor --profile
выполнение команды. Рев Вы видите несколько вызовов к методам (обозначенный mc
) к ca.desrt.dconf.Writer
интерфейс и Дух времени.
mc 1461904751 317156 3474 :1.32 /ca/desrt/dconf/Writer/user ca.desrt.dconf.Writer Change
mr 1461904751 317976 4520 3473 :1.32
mc 1461904751 320331 3475 :1.32 /org/gnome/zeitgeist/log/activity org.gnome.zeitgeist.Log InsertEvents
mc 1461904751 341474 118 :1.93 /org/gnome/zeitgeist/monitor/special org.gnome.zeitgeist.Monitor NotifyInsert
mr 1461904751 341576 119 3475 :1.32
mr 1461904751 341927 39 118 :1.93
mr 1461904751 356896 114 3474 :1.32
sig 1461904751 357892 115 /ca/desrt/dconf/Writer/user ca.desrt.dconf.Writer Notify
Если выполняют более подробное представление с dconf-monitor
Вы будете видеть, что вызовы к последовательности записей dconf байтов и духа времени регистрируют добавленную запись. Я несколько раз тестировал это, и это те же действия, выполненные в каждом случае.
Демонстрационный вывод формирует Дух времени.
method call sender=:1.93 -> dest=org.gnome.zeitgeist.SimpleIndexer serial=104 path=/org/gnome/zeitgeist/monitor/special; interface=org.gnome.zeitgeist.Monitor; member=NotifyInsert
struct {
int64 1461904249994
int64 1461904249994
}
array [
struct {
array [
string "14288"
string "1461904249994"
string "http://www.zeitgeist-project.com/ontologies/2010/01/27/zg#AccessEvent"
string "http://www.zeitgeist-project.com/ontologies/2010/01/27/zg#UserActivity"
string "application://compiz.desktop"
string ""
]
array [
array [
string "application://pyqt_clock_py.desktop"
string "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Software"
string "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SoftwareItem"
string ""
string "application/x-desktop"
string "Clock"
string "unknown"
string "application://pyqt_clock_py.desktop"
string ""
]
]
array [
]
}
]
Определенный код, который обрабатывает, который определяется в launcher/ApplicationLauncherIcon.cpp
из исходного кода Единицы
/* (Un)Stick to Launcher */
glib::Object<DbusmenuMenuitem> menu_item(dbusmenu_menuitem_new());
const char* label = !IsSticky() ? _("Lock to Launcher") : _("Unlock from Launcher");
dbusmenu_menuitem_property_set(menu_item, DBUSMENU_MENUITEM_PROP_LABEL, label);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
dbusmenu_menuitem_property_set_bool(menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
Но фактическое задание выполняется unity-shared/BamfApplicationManager.cpp
bool Application::SetSticky(bool const& param)
{
bool is_sticky = GetSticky();
if (param == is_sticky)
return false; // unchanged
bamf_view_set_sticky(bamf_view_, param);
return true; // value updated
}
Знание изменений, внесенных в dconf
и определенное поведение средства запуска может помочь нам расширить его функциональность. Примеры этого и от меня и от Jacob включают:
Особая полноценность dbus
метод для создания .desktop
файлы позволяют автоматизировать создание ярлыка для собственных приложений, которые позже могут быть заблокированы к использованию средства запуска gsettings
метод Jacob описал.