Что происходит внутри, когда я нажимаю “ Lock to launcher ” в Единстве?

На рабочем столе Unity, когда я запускаю приложение GUI, его значок появляется в панели запуска (если он еще не существует).

Теперь, когда я нажимаю правой кнопкой мыши этот значок, я либо получаю вариант Lock to Launcher или Unlock from Launcher, в зависимости от того, было ли приложение уже заблокировано для запуска или нет.

Мой вопрос: что происходит под капотом, когда я нажимаю один из этих двух вариантов, если Нет .desktop файл существует?

Может ли он автоматически создавать простые файлы .desktop, если он не может найти его, при каких условиях это может произойти, и где сохраняются сохраненные элементы пусковой установки?

1
задан 4 January 2016 в 00:17

1 ответ

Что происходит, когда вы нажимаете Lock To Launcher, это означает, что Unity изменит конкретную схему dconf для избранных Launcher и вызовет пару методов dbus. Ключом для программистов и разработчиков приложений является изменение схемы dconf. (Ответ Джейкоба полагается на gsettings, однако идея по существу такая же, как и gsettings - это просто передняя часть с проверкой работоспособности для dconf). Здесь я просто хочу представить несколько сделанных замечаний.

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

Dconf

Запуск 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 для приложения

Первоначально есть проверка независимо от того, существует ли файл .desktop для приложения. Если файл существует - хорошо. Если нет - Unity выдает dbus вызов метода org.ayatana.bamf.control.CreateLocalDesktopFile в службе org.ayatana.bamf. Это можно использовать для автоматизации создания файла .desktop. Хотя это не отображается в выходе dbus-monitor, я считаю, что это один из методов, которые могут быть использованы Unity.

Вот небольшая демонстрация:

# 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 revelations

Я выполнил блокировку и разблокировку с помощью команды dbus-monitor --profile. Ниже вы можете увидеть несколько вызовов методов (обозначенных символом mc) на интерфейсе ca.desrt.dconf.Writer и 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

Если выполнить более подробное представление с помощью dconf-monitor, вы увидите, что вызовы записи dconf последовательность байтов и записи zeitgeist записывает добавленную запись. Я проверил это несколько раз, и это те же самые действия, которые выполняются в каждом случае.

Пример формы вывода 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 [
         ]
      }
   ]

Unity Source Code:

Конкретный код, который обрабатывается, который определен в launcher/ApplicationLauncherIcon.cpp исходного кода 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);

Но фактическое задание выполняется с помощью 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, и конкретное поведение пусковой установки могут помочь нам расширить ее функциональность. Примеры этого из меня и Якоба включают:

Настройка Launcher из входного файла Переупорядочение, чтобы сделать активный верхний или нижний элемент приложения Cloning launcher от пользователя к пользователю Создание уникальной пусковой установки на рабочее пространство

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

2
ответ дан 23 May 2018 в 14:35
  • 1
    Вы будете отвечать на все вопросы, на которые ответил @JacobVlijm? : D Но хороший действительно. – Byte Commander 29 April 2016 в 08:53
  • 2
    @ByteCommander Конечно !!! Конкуренция - одна из движущих сил в мире: D Серьезно говоря, однако, просто случается, что эти типы вопросов интересуют меня. – Sergiy Kolodyazhnyy 29 April 2016 в 08:57

Другие вопросы по тегам:

Похожие вопросы: