8 votes

Que se passe-t-il en interne lorsque je clique sur "Lock to launcher" dans Unity ?

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

Maintenant, lorsque je fais un clic droit sur cette icône, j'obtiens soit l'option Lock to Launcher o Unlock from Launcher selon que l'application est déjà verrouillée ou non dans le lanceur.

Ma question est la suivante :
Qu'est-ce qui se passe sous le capot, lorsque je clique sur l'une de ces deux options si aucune .desktop existe ?

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

10voto

Jacob Vlijm Points 78990

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

Je ne suis pas sûr que cette réponse soit suffisamment approfondie "sous le capot", mais voici ce qui se passe :

Vous pouvez obtenir le contenu actuel du Lanceur de l'Unité par la commande :

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 personnes correspondantes. .desktop des fichiers.

Maintenant, lorsque vous exécutez une application GUI, lorsque vous faites un clic droit sur son icône dans le lanceur et choisissez Lock to Launcher L'élément actuellement choisi est ajouté à la liste, tandis que l'élément suivant est ajouté à la liste. Unlock from Launcher supprimera l'élément de la liste.

Modifier le lanceur Unity de manière programmatique

Je relis votre (premier) commentaire sous votre question : Vous pouvez, comme mentionné, obtenir les éléments du Lanceur actuel par la commande :

 gsettings get com.canonical.Unity.Launcher favorites

et set une liste éventuellement modifiée par la commande :

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

Vous pouvez bien sûr modifier le contenu du lanceur Unity de manière programmatique, comme cela est fait. aquí .

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

Si vous exécutez une application GUI sans qu'il n'y ait d'application existante de la .desktop Unity en crée un de base localement (dans le fichier ~/.local/share/applications ), nommé d'après l'exécutable ( application.desktop ). Dans le Exec= vous trouverez la commande que vous avez exécutée pour appeler l'application.

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

X-UnityGenerated=true

Note

Comme mentionné par @muru (merci !), dans quelques situations (exceptionnelles, comme il semble), Unity ne réussit pas à créer un "missing". .desktop d'un exécutable. Le seul exemple que j'ai pu trouver cependant était dans le cas de Tkinter Windows, qui appartiennent à pid 0 dans la sortie de wmctrl -lp .

2voto

Sergiy Kolodyazhnyy Points 97292

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.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X