¿Cómo obtener la lista de aplicaciones GUI en ejecución en Unity Launcher?

8

Necesito una lista con solo aquellas aplicaciones que están actualmente abiertas / ejecutándose en Dash, las que tienen esa pequeña flecha blanca en el lado izquierdo del icono.

¿Hay alguna forma de conseguirlo?

guión con flechas captura de pantalla

ovidb
fuente
1
¿Cuál es el contexto y cómo necesitaría que la lista esté disponible (en qué forma)?
Jacob Vlijm
Lista de ventanas abiertas? Se puede hacer fácilmente, pero como Jacob dijo, probablemente necesitaríamos saber más información
Sergiy Kolodyazhnyy
Relacionado, y muy probablemente un duplicado: askubuntu.com/q/483554/295286
Sergiy Kolodyazhnyy

Respuestas:

4

La forma de hacerlo qdbuse org.ayatana.bamfinteractuar.

Lista de aplicaciones abiertas por .desktoparchivo:

$ 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

Uso org.ayatana.bamf.matcher.RunningApplicationsy org.ayatana.bamf.view.Namemétodos

$ 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
fuente
Ahora que es impresionante!
Jacob Vlijm
@JacobVlijm Hay más variaciones en esto, pero tienen un propósito específico y requieren más código y análisis. Acabo de pegar los más simples aquí. Pero gracias :)
Sergiy Kolodyazhnyy
5

Interesante pregunta.

Como siempre, hay diferentes formas de obtener una lista de estas aplicaciones, cada una con anuncios y desventajas específicas.

Obtener una lista de procesos, representados en el Iniciador, usando la lista de ventanas

Dado que solo las aplicaciones con una ventana (asignada) aparecen en el Iniciador, usando:

wmctrl -lp 

( wmctrlno está instalado por defecto), podemos obtener una lista de ventanas abiertas y el identificador de proceso al que pertenecen las ventanas. El formato de la salida es:

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

donde para nosotros la información más importante está en:

  • la primera cadena ( 0x05204641); esta es la ventana -id
  • la tercera cadena ( 12618); esta es la identificación del proceso (pid) a la que pertenece la ventana, y
  • la última sección ( verhaal (~) - gedit); Este es el nombre de la ventana .

Una vez que tenemos el pid, podemos buscar el nombre del proceso correspondiente mediante el comando:

ps -p <pid> -o comm=

Podemos guiar los pasos anteriores y enumerar los resultados para las ventanas existentes, con el siguiente aspecto (usando python):

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

Complicaciones

Esto parece sencillo. Sin embargo, como siempre, la realidad es un poco más complicada. Hay algunas excepciones y complicaciones de las que debemos ocuparnos:

  1. Algunas ventanas pertenecerán a pid 0 , lo que generará un error al intentar obtener sus propiedades. Ventanas de Idle( pythonIDE) o tkinterson tales ventanas.
  2. Algunas ventanas no son "reales" o ventanas, como las ventanas transitorias (ventanas a las que se llama y que pertenecen a otras ventanas) o, por ejemplo, el escritorio mismo. Estas ventanas se enumeran como ventanas en la salida de wmctrl, pero no aparecen por separado en Dash.
  3. En algunos casos, el nombre de la aplicación es bastante diferente del nombre del proceso, por ejemplo, en el caso de LibreOfficeque todos los módulos tengan el nombre del proceso soffice.bin. Al mismo tiempo, ejecutar el comando soffice.bin no funcionará. En caso de que necesite identificar los módulos ( Calc, Writeretc.) por separado, necesitaría obtener información adicional, por ejemplo, del nombre de la ventana .
  4. Otro ejemplo es el nombre del proceso de gnome-terminal, como aparece en la lista de procesos, como en la salida de ps -e ww. En 14.04, gnome-terminalaparece como gnome-terminal, sin embargo, en 15.04 / 15.10 se muestra: /usr/lib/gnome-terminal/gnome-terminal-server.

Lo que necesitamos arreglar al menos

Para solucionar los problemas más importantes anteriores, debe:

  • agregue un cheque si la ventana es una ventana "real" o "normal", verificando con

    xprop -id <window_id>
    

    Si la salida incluye la línea:

    _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
    

    La ventana es una ventana válida en el sentido de Unity Launcher

  • Para corregir el nombre del proceso gnome-terminalen in 15.x(suponiendo que desea que sea el nombre del proceso presentado gnome-terminal) necesitamos agregar una excepción, para cambiar el nombre del proceso gnome-terminalsi aparece como /usr/lib/gnome-terminal/gnome-terminal-server

Guión

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

Cómo utilizar

  1. El script necesita wmctrl:

    sudo apt-get install wmctrl
    
  2. copie el script anterior en un archivo vacío, guárdelo como get_running.py

  3. ejecútelo con el comando:

    python3 /path/to/get_running.py
    

    Saldrá como:

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

    o, corre con el argumento -list:

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

Notas

De su pregunta, no está completamente claro cuál es exactamente el propósito de la lista encontrada. Si necesita tener el nombre de la aplicación, tal como aparece en la interfaz (nombres "legibles"), un enfoque completamente diferente podría ser adecuado:

  • Todas las aplicaciones instaladas globalmente tienen un .desktoparchivo /usr/share/applications. En la mayoría de los casos, podemos concluir el nombre del proceso y el nombre de la interfaz de la aplicación a partir de su .desktoparchivo. Con esta información, podríamos crear una lista de aplicaciones GUI en ejecución relativamente fácil, presentada por su nombre "legible".

Sin embargo, también en este caso, la realidad también es más complicada que la teoría, como se explica aquí .

Jacob Vlijm
fuente