Que se passe-t-il lorsque vous cliquez Lock To Launcher est qu'Unity va modifier certaines dconf
pour les favoris du lanceur et d'appeler un couple de dbus
méthodes. L'élément clé pour les programmeurs et les développeurs d'applications est le changement d'attitude de l'utilisateur. dconf
schéma. ( La réponse de Jacob s'appuie sur gsettings
Cependant, l'idée est essentiellement la même que gsettings
est juste un front-end avec un contrôle de sanité pour dconf
). Ici, je veux juste présenter quelques observations faites.
Remarque : ici, je teste tout avec une application Python personnalisée qui n'a pas d'interface avec l'utilisateur. .desktop
fichier
Changements dans Dconf
Running dconf watch /
révélera que c'est ce qui est modifié :
$ 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']
Création d'un fichier .desktop pour l'application
Dans un premier temps, il est vérifié si la .desktop
existe pour l'application. Si le fichier existe, c'est bien. Sinon, Unity émettra un dbus
Appel à org.ayatana.bamf.control.CreateLocalDesktopFile
méthode sur org.ayatana.bamf
service. Cela peut être utilisé pour automatiser .desktop
création de fichiers. Bien que cela n'apparaisse pas dans l'historique de la dbus-monitor
sortie, je crois que c'est l'une des méthodes qui peuvent être utilisées Unité.
Voici une petite démo :
# 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']
Il existe une méthode dbus différente, qui détruit le fichier :
révélations sur le dbus-monitor
J'ai effectué une action de verrouillage et de déverrouillage avec dbus-monitor --profile
commande en cours d'exécution. Ci-dessous vous pouvez voir plusieurs appels à des méthodes ( désignées par mc
) à ca.desrt.dconf.Writer
interface et Zeitgeist.
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
Si vous effectuez une vue plus détaillée avec dconf-monitor
vous verrez que l'appel à dconf écrit une séquence d'octets et que zeitgeist enregistre l'entrée ajoutée. J'ai testé cela plusieurs fois, et ce sont les mêmes actions qui sont effectuées dans chaque cas.
Exemple de formulaire de sortie Zeitgeist.
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 [
]
}
]
Code source Unity :
Le code spécifique qui gère cela est défini dans launcher/ApplicationLauncherIcon.cpp
du code source d'Unity
/* (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);
Mais le travail réel est effectué par 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
}
Où cela nous mène-t-il ?
Connaître les changements apportés à dconf
et le comportement spécifique du lanceur peuvent nous aider à étendre sa fonctionnalité. Voici quelques exemples de ce que nous avons fait, Jacob et moi :
L'utilité particulière de la dbus
méthode pour créer .desktop
permet d'automatiser la création de raccourcis pour les applications personnalisées, qui peuvent ensuite être verrouillées dans le lanceur à l'aide de l'option gsettings
méthode décrite par Jacob.