UnityデスクトップでGUIアプリケーションを起動すると、ランチャーにアイコンが表示されます(まだない場合)。
このアイコンを右クリックすると、オプションが表示されます Lock to Launcher または Unlock from Launcher、アプリケーションが既にランチャーにロックされているかどうかによって異なります。
私の質問は:.desktop
ファイルが存在しない場合、これら2つのオプションのいずれかをクリックすると、内部で何が起こりますか?
簡単な.desktop
ファイルが見つからない場合、その条件が発生する可能性があり、ピン留めされたランチャーアイテムがどこに保存されるかを自動的に作成できますか?
この答えが「ボンネットの下」で十分に深いかどうかはわかりませんが、これが起こることです:
次のコマンドを使用して、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 リストからアイテムを削除します。
質問の下にある(最初の)コメントを読み直します:前述のように、getコマンドで現在のランチャーアイテムを取得できます。
gsettings get com.canonical.Unity.Launcher favorites
およびsetコマンドによって変更される可能性のあるリスト:
gsettings set com.canonical.Unity.Launcher favorites "[item1, item2, etc]"
その後、もちろん、 here のように、Unity Launcherのコンテンツをプログラムで編集できます。
既存の.desktop
ファイルなしでGUIアプリケーションを実行すると、Unityは実行可能ファイル(~/.local/share/applications
)にちなんで名付けられた基本的なものを(application.desktop
に)ローカルに作成します。 Exec=
行には、アプリケーションを呼び出すために実行したコマンドがあります。
この方法で作成された.desktop
ファイルを調べると、次の行が含まれています。
X-UnityGenerated=true
@muru(ありがとう!)で述べたように、いくつかの(例外的なように思える)状況では、Unityは実行可能ファイルの「欠落」.desktop
ファイルの作成に成功しません。ただし、見つけることができる唯一の例は、pid 0
の出力でwmctrl -lp
が所有するTkinterウィンドウの場合です。
クリックするとどうなりますか Lock To Launcher オプションは、Unityがランチャーのお気に入りの特定のdconf
スキーマを変更し、いくつかのdbus
メソッドを呼び出すことです。プログラマーとアプリケーション開発者にとって重要なのは、dconf
スキーマの変更です。 (Jacobの答えはgsettings
に依存していますが、gsettings
はdconf
の健全性チェックを備えたフロントエンドにすぎません。ここでは、いくつかの観察結果を提示したいだけです。
サイドノート:ここでは、.desktop
ファイルがないカスタムpythonアプリですべてをテストしています
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
ファイルが存在するかどうかがチェックされます。ファイルが存在する場合-良い。そうでない場合-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 --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ソースコードの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
メソッドを使用して後でランチャーにロックできるカスタム作成アプリのショートカット作成を自動化できます。