J'ai besoin d'une liste avec uniquement les applications qui sont actuellement ouvertes/en cours d'exécution dans Dash, celles qui ont cette petite flèche blanche sur le côté gauche de l'icône.
Y a-t-il un moyen de l'obtenir?
La façon de le faire avec l'interface qdbus
et org.ayatana.bamf
.
Liste des applications ouvertes par fichier .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
Utilisation des méthodes org.ayatana.bamf.matcher.RunningApplications
et 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
Question interessante.
Comme toujours, il existe différentes manières d’obtenir une liste de ces applications, chacune avec ses propres inconvénients et inconvénients.
Etant donné que seules les applications avec une fenêtre (mappée) apparaissent dans le lanceur, utilisez:
wmctrl -lp
(wmctrl
n'est pas installé par défaut), nous pouvons obtenir une liste des fenêtres ouvertes et l'identifiant du processus auquel appartiennent les fenêtres. Le format de la sortie est:
0x05204641 0 12618 jacob-System-Product-Name verhaal (~) - gedit
où sont pour nous les informations les plus importantes:
0x05204641
); c'est la fenêtre -id 12618
); c'est l'identifiant du processus (pid) auquel la fenêtre appartient, etverhaal (~) - gedit
); c'est le nom de la fenêtre .Une fois que nous avons le pid, nous pouvons rechercher le nom du processus correspondant par la commande:
ps -p <pid> -o comm=
Nous pouvons créer un script pour les étapes ci-dessus et répertorier le ou les résultats des fenêtres existantes sous la forme suivante (avec python
):
{'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'Thunderbird', 'soffice.bin'}
Cela semble simple. Cependant, comme toujours, la réalité est un peu plus compliquée. Il y a quelques exceptions et complications dont nous devons nous occuper:
Idle
(python
IDE) ou tkinter
sont de telles fenêtres.wmctrl
, mais n'apparaissent pas séparément dans le tiret.LibreOffice
où tous les modules ont le nom de processus soffice.bin
. En même temps, l’exécution de la commande soffice.bin
ne fonctionnera pas. Si vous devez identifier les modules (Calc
, Writer
etc.) séparément, vous devez obtenir des informations supplémentaires. informations, à partir du nom de la fenêtre , par exemple.gnome-terminal
, tel qu'il apparaît dans la liste des processus, comme dans la sortie de ps -e ww
. Dans 14.04, gnome-terminal
apparaît en tant que gnome-terminal
, cependant, dans 15.04/15.10, il est indiqué: /usr/lib/gnome-terminal/gnome-terminal-server
.Pour résoudre les problèmes les plus importants ci-dessus, vous devez:
ajouter une vérification si la fenêtre est une fenêtre "réelle" ou "normale", en vérifiant avec
xprop -id <window_id>
Si la sortie comprend la ligne:
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
La fenêtre est une fenêtre valide au sens du lanceur Unity.
gnome-terminal
dans 15.x
(en supposant que vous vouliez que le nom du processus présenté soit gnome-terminal
), nous devons ajouter une exception pour renommer le nom du processus en gnome-terminal
s'il apparaît ainsi: /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)
Le script a besoin de wmctrl
:
Sudo apt-get install wmctrl
copiez le script ci-dessus dans un fichier vide, enregistrez-le sous le nom get_running.py
lancez le par la commande:
python3 /path/to/get_running.py
Il sortira comme:
{'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'Thunderbird', 'soffice.bin'}
ou, exécutez avec l'argument -list
:
Thunderbird
nautilus
gnome-terminal
firefox
gedit
GuitarPro.exe
soffice.bin
D'après votre question, le but de la liste trouvée n'est pas tout à fait clair. Si vous avez besoin du nom de l'application, tel qu'il apparaît dans l'interface (noms "lisibles"), une approche complètement différente pourrait convenir:
.desktop
dans /usr/share/applications
. Dans la plupart des cas, nous pouvons conclure le nom du processus et le nom d'interface de l'application à partir de son fichier .desktop
. En utilisant ces informations, nous pourrions créer relativement facilement une liste d’applications graphiques en cours d’exécution, présentées sous leur nom "lisible".Dans ce cas également, la réalité est aussi plus compliquée que la théorie, comme expliqué ici .