web-dev-qa-db-ja.com

Unityで[ランチャーにロック]をクリックすると、内部で何が起こりますか?

UnityデスクトップでGUIアプリケーションを起動すると、ランチャーにアイコンが表示されます(まだない場合)。

このアイコンを右クリックすると、オプションが表示されます Lock to Launcher または Unlock from Launcher、アプリケーションが既にランチャーにロックされているかどうかによって異なります。

私の質問は:
.desktopファイルが存在しない場合、これら2つのオプションのいずれかをクリックすると、内部で何が起こりますか?

簡単な.desktopファイルが見つからない場合、その条件が発生する可能性があり、ピン留めされたランチャーアイテムがどこに保存されるかを自動的に作成できますか?

5
Byte Commander

ランチャーとの間でアプリケーションをロック/ロック解除するとどうなりますか

この答えが「ボンネットの下」で十分に深いかどうかはわかりませんが、これが起こることです:

次のコマンドを使用して、Unityランチャーの現在のコンテンツを取得できます。

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、現在選択されているアイテムがリストに追加され、 Unlock from Launcher リストからアイテムを削除します。

Unity Launcherをプログラムで編集する

質問の下にある(最初の)コメントを読み直します:前述のように、getコマンドで現在のランチャーアイテムを取得できます。

 gsettings get com.canonical.Unity.Launcher favorites

およびsetコマンドによって変更される可能性のあるリスト:

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

その後、もちろん、 here のように、Unity Launcherのコンテンツをプログラムで編集できます。

アプリケーションに.desktopファイルがない場合

既存の.desktopファイルなしでGUIアプリケーションを実行すると、Unityは実行可能ファイル(~/.local/share/applications)にちなんで名付けられた基本的なものを(application.desktopに)ローカルに作成します。 Exec=行には、アプリケーションを呼び出すために実行したコマンドがあります。

この方法で作成された.desktopファイルを調べると、次の行が含まれています。

X-UnityGenerated=true

注意

@muru(ありがとう!)で述べたように、いくつかの(例外的なように思える)状況では、Unityは実行可能ファイルの「欠落」.desktopファイルの作成に成功しません。ただし、見つけることができる唯一の例は、pid 0の出力でwmctrl -lpが所有するTkinterウィンドウの場合です。

9
Jacob Vlijm

クリックするとどうなりますか Lock To Launcher オプションは、Unityがランチャーのお気に入りの特定のdconfスキーマを変更し、いくつかのdbusメソッドを呼び出すことです。プログラマーとアプリケーション開発者にとって重要なのは、dconfスキーマの変更です。 (Jacobの答えはgsettingsに依存していますが、gsettingsdconfの健全性チェックを備えたフロントエンドにすぎません。ここでは、いくつかの観察結果を提示したいだけです。

サイドノート:ここでは、.desktopファイルがないカスタムpythonアプリですべてをテストしています

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はorg.ayatana.bamf.control.CreateLocalDesktopFileサービスでorg.ayatana.bamfメソッドへのdbus呼び出しを発行します。これは、.desktopファイルの作成を自動化するために使用できます。 、これはdbus-monitor出力には表示されませんが、Unityで使用できる方法の1つだと思います。

これは小さなデモです:

# 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の啓示

dbus-monitor --profileコマンドを実行して、ロックとロック解除のアクションを実行しました。以下に、ca.desrt.dconf.WriterインターフェイスとZeitgeistに対するメソッド(mcで指定)の呼び出しをいくつか示します。

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ソースコード:

Unityソースコードの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に加えられた変更とランチャーの特定の動作を知ることは、その機能を拡張するのに役立ちます。私とジェイコブの両方からの例は次のとおりです。

.desktopファイルを作成するdbusメソッドの特定の有用性により、ジェイコブが説明したgsettingsメソッドを使用して後でランチャーにロックできるカスタム作成アプリのショートカット作成を自動化できます。

2