web-dev-qa-db-ja.com

Unityランチャーで実行中のGUIアプリケーションのリストを取得する方法は?

Dashで現在開いている/実行しているアプリ(アイコンの左側にその小さな白い矢印があるアプリ)のみを含むリストが必要です。

入手する方法はありますか?

dash with arrows screenshoot

8
ovidb

qdbusおよびorg.ayatana.bamfインターフェイスでそれを行う方法。

.desktopファイルによる開いているアプリケーションのリスト:

$ 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

org.ayatana.bamf.matcher.RunningApplicationsおよびorg.ayatana.bamf.view.Nameメソッドの使用

$ qdbus org.ayatana.bamf /org/ayatana/bamf/matcher  \                          
> org.ayatana.bamf.matcher.RunningApplications | \                             
> xargs -I {} qdbus org.ayatana.bamf {} org.ayatana.bamf.view.Name
Firefox Web Browser
MY CUSTOM TERMINAL
Compiz
4

興味深い質問。

いつものように、これらのアプリケーションのリストを取得するにはさまざまな方法があり、それぞれに特定の広告と欠点があります。

ウィンドウリストを使用して、ランチャーに表示されるプロセスのリストを取得する

(マップされた)ウィンドウを持つアプリケーションのみがランチャーに表示されるため、以下を使用します。

wmctrl -lp 

wmctrlはデフォルトではインストールされません)、開いているウィンドウとウィンドウが属するプロセスIDのリストを取得できます。出力の形式は次のとおりです。

0x05204641  0 12618  jacob-System-Product-Name verhaal (~) - gedit

私たちにとって最も重要な情報は次のとおりです。

  • 最初の文字列(0x05204641);これはwindow -id
  • 3番目の文字列(12618);これは、プロセスid(pid)ウィンドウが属する、および
  • 最後のセクション(verhaal (~) - gedit);これはウィンドウnameです。

Pidを取得したら、対応するプロセスnameをコマンドで検索できます。

ps -p <pid> -o comm=

上記の手順をスクリプト化して、既存のウィンドウの出力を一覧表示できます(pythonを使用)。

{'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'Thunderbird', 'soffice.bin'}

合併症

これは簡単そうです。しかし、いつものように、現実はもう少し複雑です。注意が必要ないくつかの例外と合併症があります。

  1. 一部のウィンドウは pid に属し、プロパティを取得しようとするとエラーが発生します。 Idlepython IDE)またはtkinterのウィンドウはそのようなウィンドウです。
  2. 一部のウィンドウは、「実際の」ウィンドウではなく、一時ウィンドウ(他のウィンドウから呼び出され、他のウィンドウに属しているウィンドウ)やデスクトップ自体などのウィンドウです。これらのウィンドウは、wmctrlの出力にウィンドウとしてリストされますが、Dashに個別には表示されません。
  3. 場合によっては、アプリケーションの名前はプロセス名とはまったく異なります。たとえば、すべてのモジュールのプロセス名がsoffice.binであるLibreOfficeの場合です。同時に、commandsoffice.binを実行しても機能しません。 modulesCalcWriterなど)を個別に識別する必要がある場合は、追加を取得する必要があります。たとえば、ウィンドウのnameからの情報。
  4. 別の例は、gnome-terminalの出力のように、プロセスリストに表示されるps -e wwのプロセス名です。 14.04では、gnome-terminalgnome-terminalとして表示されますが、15.04/15.10では/usr/lib/gnome-terminal/gnome-terminal-serverと表示されます。

修正する必要があるもの少なくとも

上記の最も重要な問題を修正するには、以下を行う必要があります。

  • ウィンドウが「実際の」ウィンドウか「通常の」ウィンドウかをチェックし、

    xprop -id <window_id>
    

    出力に次の行が含まれる場合:

    _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
    

    ウィンドウは、Unityランチャーの意味で有効なウィンドウです

  • gnome-terminal15.xのプロセス名を修正するには(提示されたプロセス名をgnome-terminalにしたい場合)、例外を追加して、プロセス名をgnome-terminalに変更し、/usr/lib/gnome-terminal/gnome-terminal-serverとして表示される場合

脚本

#!/usr/bin/env python3
import subprocess
import sys

try:
    listed = sys.argv[1]
except IndexError:
    listed = []

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()

def check_wtype(w_id):
    # check the type of window; only list "NORMAL" windows
    return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])

def get_process(w_id):
    # get the name of the process, owning the window
    proc = get(["ps", "-p", w_id, "-o", "comm="])
    proc = "gnome-terminal" if "gnome-terminal" in proc else proc
    return proc

wlist = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"])\
         .decode("utf-8").splitlines()]

validprocs = set([get_process(w[2]) for w in wlist if check_wtype(w[0]) == True])

if listed == "-list":
    for p in validprocs:
        print(p)
else:
    print(validprocs)

使い方

  1. スクリプトにはwmctrlが必要です。

    Sudo apt-get install wmctrl
    
  2. 上記のスクリプトを空のファイルにコピーし、get_running.pyとして保存します

  3. 次のコマンドで実行します:

    python3 /path/to/get_running.py
    

    次のように出力されます。

    {'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'Thunderbird', 'soffice.bin'}
    

    または、引数-listを指定して実行します。

    Thunderbird
    nautilus
    gnome-terminal
    firefox
    gedit
    GuitarPro.exe
    soffice.bin
    

ノート

あなたの質問から、見つかったリストの正確な目的が完全に明確ではありません。インターフェイスに表示されるアプリケーションの名前(「読み取り可能な」名前)が必要な場合は、まったく異なるアプローチが適しています。

  • グローバルにインストールされたすべてのアプリケーションは、.desktop/usr/share/applicationsファイルを持っています。ほとんどの場合、.desktopファイルからアプリケーションのプロセス名のインターフェイス名を結論付けることができます。この情報を使用すると、実行中のGUIアプリケーションのリストを「読みやすい」名前で比較的簡単に作成できます。

ただし、この場合も、説明は ここ のように、現実は理論よりも複雑です。

5
Jacob Vlijm