web-dev-qa-db-fra.com

Que se passe-t-il en interne lorsque je clique sur "Verrouiller pour lancer" dans Unity?

Dans le bureau Unity, lorsque je lance une application graphique, son icône apparaît dans le lanceur (si ce n'est déjà fait).

Maintenant, quand je fais un clic droit sur cette icône, je reçois l'option Lock to Launcher ou Unlock from Launcher, selon que l’application est déjà verrouillée ou non par le lanceur.

Ma question est:
Que se passe-t-il sous le capot lorsque je clique sur l'une de ces deux options si aucun fichier .desktop n'existe?

Peut-il créer automatiquement de simples fichiers .desktop s'il ne parvient pas à en trouver un, dans quelles conditions cela peut-il se produire et où les éléments de lanceur épinglés sont-ils enregistrés?

5
Byte Commander

Que se passe-t-il si vous verrouillez/déverrouillez une application vers/depuis le lanceur?

Je ne sais pas si cette réponse est assez profonde "sous le capot", mais voici ce qui se passe:

Vous pouvez obtenir le contenu actuel du lanceur d'Unity à l'aide de la commande suivante:

gsettings get com.canonical.Unity.Launcher favorites

Il produira une liste, ressemblant à:

['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']

Les mentions dans la liste sont évidemment basées sur les noms des fichiers .desktop correspondants.

Maintenant, lorsque vous exécutez une application graphique, lorsque vous cliquez avec le bouton droit sur son icône dans le lanceur et choisissez Lock to Launcher, L'élément actuellement sélectionné est ajouté à la liste, tandis que Unlock from Launcher va supprimer l'élément de la liste.

Modification du programme de lancement d'unité par programme

Relisez votre (premier) commentaire ci-dessous votre question: Vous pouvez, comme mentionné, obtenir les éléments actuels du programme de lancement par la commande:

 gsettings get com.canonical.Unity.Launcher favorites

et définir une liste éventuellement modifiée par la commande:

 gsettings set com.canonical.Unity.Launcher favorites "[item1, item2, etc]"

Vous pouvez ensuite bien sûr éditer le contenu du Unity Launcher par programmation, comme cela est fait ici .

Si l'application n'a pas de fichier .desktop

Si vous exécutez une application graphique sans fichier .desktop existant, Unity en crée une de base en local (dans ~/.local/share/applications), nommée d'après l'exécutable (application.desktop). Dans la ligne Exec=, vous trouverez la commande que vous avez exécutée pour appeler l'application.

Si vous regardez dans un fichier .desktop, créé de cette façon, il inclut la ligne:

X-UnityGenerated=true

Remarque

Comme mentionné par @muru (merci!), Dans quelques situations exceptionnelles, Unity ne parvient pas à créer un fichier "manquant" .desktop d'un exécutable. Le seul exemple que j'ai pu trouver était toutefois dans le cas de fenêtres Tkinter, qui appartiennent à pid 0 dans la sortie de wmctrl -lp.

9
Jacob Vlijm

Qu'est-ce qui se passe quand vous cliquez Lock To Launcher L’option Unity modifie le schéma spécifique dconf des favoris du lanceur et appelle plusieurs méthodes dbus. La clé pour les programmeurs et les développeurs d'applications est la modification du schéma dconf. (La réponse de Jacob s'appuie sur gsettings, mais l'idée est essentiellement la même que gsettings n'est qu'un test frontal avec contrôle de cohérence pour dconf). Ici, je veux juste présenter quelques observations.

Note latérale: ici, je teste tout avec une application personnalisée python qui n'a pas de fichier .desktop

Changements Dconf

Lancer dconf watch / révélera que c'est ce qui est changé:

$ 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 du fichier .desktop pour l'application

Initialement, il est vérifié si le fichier .desktop existe pour l'application. Si le fichier existe - bien. Sinon, Unity émettra un appel dbus à la méthode org.ayatana.bamf.control.CreateLocalDesktopFile sur le service org.ayatana.bamf. Ceci peut être utilisé pour automatiser la création de fichier .desktop. Bien que cela n'apparaisse pas dans la sortie dbus-monitor, je pense que c'est l'une des méthodes pouvant être utilisées par Unity.

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 dbus-moniteur

J'ai effectué une action de verrouillage et de déverrouillage avec la commande dbus-monitor --profile en cours d'exécution. Vous pouvez voir ci-dessous plusieurs appels à des méthodes (désignées par mc) vers 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 les appels à dconf écrit une séquence d'octets et que le journal zeitgeist enregistre l'entrée ajoutée. J'ai testé cela plusieurs fois, et ce sont les mêmes actions 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 de l'unité:

Le code spécifique qui gère est défini dans launcher/ApplicationLauncherIcon.cpp du code source de 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 modifications apportées à dconf et le comportement spécifique du lanceur peut nous aider à étendre ses fonctionnalités. Les exemples de cela de moi et de Jacob incluent:

L'utilité particulière de la méthode dbus pour la création de fichiers .desktop permet d'automatiser la création de raccourcis pour les applications personnalisées, qui peuvent ensuite être verrouillées au lanceur à l'aide de la méthode gsettings décrite par Jacob.

2