Wie kann ich die Liste der ausgeführten GUI-Anwendungen im Unity Launcher abrufen?

8

Ich benötige eine Liste mit nur den Apps, die derzeit in Dash geöffnet sind / ausgeführt werden. Diese Apps haben die kleinen weißen Pfeile auf der linken Seite des Symbols.

Gibt es eine Möglichkeit, es zu bekommen?

Strich mit Pfeilen Screenshoot

ovidb
quelle
1
Was ist der Kontext und wie müsste die Liste verfügbar sein (in welcher Form)?
Jacob Vlijm
Liste der geöffneten Fenster? Kann leicht gemacht werden, aber wie Jacob sagte, müssten wir wahrscheinlich mehr Informationen wissen
Sergiy Kolodyazhnyy
Verwandte und sehr wahrscheinlich ein Duplikat: askubuntu.com/q/483554/295286
Sergiy Kolodyazhnyy

Antworten:

4

Der Weg, es mit qdbusund org.ayatana.bamfSchnittstelle zu tun .

Liste der geöffneten Anwendungen nach .desktopDatei:

$ 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

Verwendung org.ayatana.bamf.matcher.RunningApplicationsund org.ayatana.bamf.view.NameMethoden

$ 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
Sergiy Kolodyazhnyy
quelle
Das ist beeindruckend!
Jacob Vlijm
@JacobVlijm Es gibt mehr Variationen davon, aber sie haben einen bestimmten Zweck und erfordern mehr Code und Analyse. Ich habe gerade die einfachsten hier eingefügt. Aber danke :)
Sergiy Kolodyazhnyy
5

Interessante Frage.

Wie immer gibt es verschiedene Möglichkeiten, eine Liste dieser Anwendungen zu erhalten, jede mit spezifischen Anzeigen- und Nachteilen.

Abrufen einer Liste von Prozessen, die im Launcher mithilfe der Fensterliste dargestellt werden

Da im Launcher nur Anwendungen mit einem (zugeordneten) Fenster angezeigt werden, verwenden Sie:

wmctrl -lp 

( wmctrlist nicht standardmäßig installiert), wir können eine Liste der geöffneten Fenster und die Prozess-ID erhalten, zu der die Fenster gehören. Das Format der Ausgabe lautet:

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

Wo für uns die wichtigsten Informationen sind:

  • die erste Zeichenfolge ( 0x05204641); Dies ist die Fenster-ID
  • die dritte Zeichenfolge ( 12618); Dies ist die Prozess-ID (pid), zu der das Fenster gehört, und,
  • der letzte Abschnitt ( verhaal (~) - gedit); dies ist der Fenstername .

Sobald wir die pid haben, können wir den entsprechenden Prozess nachschlagen Namen mit dem Befehl:

ps -p <pid> -o comm=

Wir können die obigen Schritte skripten und die Ausgabe (n) für vorhandene Fenster wie folgt pythonauflisten:

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

Komplikationen

Dies scheint unkompliziert zu sein. Die Realität ist jedoch wie immer etwas komplizierter. Es gibt einige Ausnahmen und Komplikationen, um die wir uns kümmern müssen:

  1. Einige Fenster gehören zu pid 0 , was beim Versuch, ihre Eigenschaften abzurufen , einen Fehler auslöst. Fenster von Idle( pythonIDE) oder tkintersind solche Fenster.
  2. Einige Fenster sind keine "echten" oder Fenster, wie vorübergehende Fenster (Fenster, die von anderen Fenstern aufgerufen werden und zu anderen Fenstern gehören) oder beispielsweise der Desktop selbst. Diese Fenster werden in der Ausgabe von als Fenster aufgeführt wmctrl, in Dash jedoch nicht separat angezeigt.
  3. In einigen Fällen unterscheidet sich der Name der Anwendung erheblich vom Prozessnamen, z. B. LibreOfficewenn alle Module den Prozessnamen haben soffice.bin. Gleichzeitig funktioniert das Ausführen des Befehls soffice.bin nicht. Für den Fall , müssen Sie die identifizieren Module ( Calc, Writeretc.) getrennt, müssen Sie zusätzliche Informationen zu erhalten, aus dem Fenster Namen zum Beispiel.
  4. Ein weiteres Beispiel ist der Prozessname von gnome-terminal, wie er in der Prozessliste angezeigt wird, wie in der Ausgabe von ps -e ww. In 14.04 gnome-terminalerscheint jedoch wie gnome-terminalin 15.04 / 15.10 : /usr/lib/gnome-terminal/gnome-terminal-server.

Was wir zumindest reparieren müssen

Um die oben genannten wichtigsten Probleme zu beheben, müssen Sie:

  • Fügen Sie eine Überprüfung hinzu, ob das Fenster ein "echtes" oder "normales" Fenster ist, und überprüfen Sie mit

    xprop -id <window_id>
    

    Wenn die Ausgabe die Zeile enthält:

    _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
    

    Das Fenster ist ein gültiges Fenster im Sinne des Unity Launcher

  • Um den Prozessnamen von gnome-terminalin zu 15.xkorrigieren (vorausgesetzt, Sie möchten, dass der präsentierte Prozessname lautet gnome-terminal), müssen Sie eine Ausnahme hinzufügen, um den Prozessnamen in umzubenennen, gnome-terminalwenn er als angezeigt wird /usr/lib/gnome-terminal/gnome-terminal-server

Skript

#!/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)

Wie benutzt man

  1. Das Skript benötigt wmctrl:

    sudo apt-get install wmctrl
    
  2. Kopieren Sie das obige Skript in eine leere Datei und speichern Sie es unter get_running.py

  3. Führen Sie es mit dem folgenden Befehl aus:

    python3 /path/to/get_running.py
    

    Es wird wie folgt ausgegeben:

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

    oder führen Sie mit dem Argument aus -list:

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

Anmerkungen

Aus Ihrer Frage geht nicht ganz hervor, was genau der Zweck der gefundenen Liste ist. Wenn Sie den Namen der Anwendung benötigen, wie er in der Benutzeroberfläche angezeigt wird ("lesbare" Namen), ist möglicherweise ein völlig anderer Ansatz geeignet:

  • Alle global installierten Anwendungen haben eine .desktopDatei in /usr/share/applications. In den meisten Fällen können wir den Prozessnamen und den Schnittstellennamen der Anwendung aus ihrer .desktopDatei schließen. Mit diesen Informationen könnten wir relativ einfach eine Liste laufender GUI-Anwendungen erstellen, die durch ihren "lesbaren" Namen dargestellt wird.

Auch in diesem Fall ist die Realität jedoch komplizierter als die Theorie, wie hier erläutert .

Jacob Vlijm
quelle