xdotool: Cómo buscar ventanas por título y clase con diferentes patrones (similar a AutoHotkey)

10

xdotool le permite buscar ventanas usando su subcomando de búsqueda. Necesito ubicar una ventana que tenga la clase 'gvim' y el título que contenga la palabra 'TODO'. ¿Cómo hago esto?

Lo que he intentado:

  • Puede hacerlo xdotool search --name --class, pero solo aceptaría un patrón para el nombre y el título.
  • xdotool admite el encadenamiento de comandos, pero no pude encontrar una manera de encadenar dos llamadas de búsqueda: la segunda simplemente anula la primera.
t7ko
fuente
xdotoolapesta ... esta es una operación tan simple y no hay forma de hacerlo con elegancia.
Yan King Yin

Respuestas:

13

Mi ayuda de xdotool me informa que sus dos interruptores son iguales (xdotool versión 3.20150503.1),

--name          check regexp_pattern agains the window name
--title         DEPRECATED. Same as --name.

y como tal no hace nada. Mi xdotool hace lo mismo que el tuyo al reemplazar la pila de la ventana, así que lo hice con un script de shell. A continuación se entrega un script de shell que hace lo que desea:

pids=$(xdotool search --class "gvim")
for pid in $pids; do
    name=$(xdotool getwindowname $pid)
    if [[ $name == *"TODO"* ]]; then
        #Do what you want, $pid is your sought for PID,
        #matching both class gvim and TODO in title
    fi
done

Los asteriscos en la instrucción if están ahí para hacer una coincidencia de subcadena para TODOque pueda aparecer en cualquier parte del título.

DS
fuente
Sí, lo siento, un error tipográfico, quise decir --nombre y --clase. Lo arreglará ahora.
t7ko
@DS, ¿puede decir por qué xdotool search --class "gedit" ahora solo funcionaría para gedit, pero funcionaría para cualquier otra ventana? Misma historia con la utilidad xprop.
Gonki
6

Pude identificar una solución corta y unix:

comm -12 \
  <(xdotool search --name  'title-pattern'  | sort) \
  <(xdotool search --class 'class-pattern'  | sort)
t7ko
fuente
3

¡Aquí hay otra solución que se adhiere a la forma UNIX!

A primera vista, no es tan hermoso como el tuyo, @ t7ko:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

Pero ten paciencia conmigo! Hay algo de belleza oculta en ella.

En resumen,

  1. tiene una estructura lineal , en lugar de una estructura de árbol, como una en lugar de dos dimensiones
  2. utiliza una sintaxis de shell más conocida .
  3. en realidad responde a su pregunta: localiza la ventana.

(Si estos puntos son ventajas depende del contexto, ignoremos este aspecto * ).

Mostraré el mismo código en un diseño más estructurado a continuación, para que sea más fácil de entender paso a paso.
Pero tenga en cuenta que la sangría es para explicar el comando: no indica anidamiento, todo sigue siendo una tubería lineal de UNIX.

El mismo comando, solo dividido después de las tuberías ( |):

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry |
    sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

El comando completo, como se muestra arriba, proporciona la ubicación de píxeles de la gvimventana, devolviendo las coordenadas de píxeles en relación con la esquina superior izquierda de la pantalla actual (posiblemente virtual) como x,y, como 42,433, o tal vez -5375,-3809cuando está en la primera de cuatro por cuatro pantallas virtuales , y el actual está en algún lugar del lado derecho.

Por ahora, acortaré el comando para encontrar solo una ID de ventana X11; tal vez eso es todo lo que realmente necesitaba el OP, no estoy seguro:

La tubería de comando acortada, un comando de shell separado en cada línea:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO'

Ahora, comienza a ser legible:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool search --all --pid {} --name 'TODO' 

El xdotoolcomando searchse utiliza para buscar ventanas con la " clase " gvim, dejando de lado algunas ventanas "internas". El resultado se enumera como PID's (identificadores de proceso).
Para cada uno PID, xargsejecuta otro xdotool search, verificando el "nombre" para nuestro patrón de ejemplo TODO, después de verificar el PID.

(Por si acaso: las líneas que terminan en \- llamadas líneas de continuación - deben terminar realmente con \y sin espacios en blanco antes de la nueva línea).

Ahora de vuelta al comando original:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool \
        search --all --pid {} --name 'TODO' \
        getwindowgeometry |
sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

La parte restante enumera algunos detalles sobre la ventana, incluida la posición. El sedcomando coincide y devuelve solo el x,yvalor de posición.

Como ejemplo, ejecutar el comando en la parte superior de mi 16ª pantalla virtual (de 4 por 4), con un "TODO" gvimen la pantalla 1:

$ xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'
-7653,-4732

*) Descargo de responsabilidad: prefiero el código de @ t7ko. ¡Mucho!

Volker Siegel
fuente
Usar --onlyvisiblees bueno. Me ayudó con un problema similar. Thunderbird puede comenzar con 14 ventanas y solo una o dos están en el escritorio. No tengo idea para qué son los otros. Por cierto, solo se pueden mostrar los medios visibles, no solo se muestran inmediatamente en el escritorio actual.
Joe
1

Respuesta corta y elegante (que usa wmctrl):

result=$(wmctrl -l | grep 'TODO - gvim' | grep -Eo '0x[0-9a-f]+')

El ID de la ventana resultante está en hexadecimal, por lo que debe convertirlo a decimal (utilizado por xdotool):

printf "%d\n" $result

Entonces puedes hacer lo que sea con xdotool.

Yan King Yin
fuente
1
wmctrlel manual dice que -lno imprime la clase de ventana, solo el título; así que su fragmento de código no resuelve mi problema "buscar por título Y clase".
t7ko
1
wmctrl -lxproporciona la clase
david.perez