¿Cómo encuentro la ID de la ventana X debajo del puntero del mouse en bash?

20

De un script bash, ¿hay alguna forma de obtener la ID de la ventana X debajo del puntero del mouse?

(editar) Necesito que el proceso no sea interactivo.

Peter.O
fuente

Respuestas:

25

xdotoolexpone la ubicación del puntero ( xdotool getmouselocation), y las versiones recientes (desde 2.20110530.1) también indican qué ventana está en esa ubicación . Ninguno de xwininfo, wmctrlo versiones anteriores de xdotoolparecer que tienen una forma para que coincida con una ventana por una posición de la pantalla donde es visible.

La llamada a la biblioteca X subyacente es XQueryPointer(correspondiente a un QueryPointermensaje). Aquí hay un script simple de envoltura de Python alrededor de esta llamada (usando ctypes). Error de comprobación omitido en gran medida. Asume que está usando la pantalla 0 (si no sabía que las pantallas podrían tener más de una pantalla, ignore esto).

#! /usr/bin/env python
import sys
from ctypes import *
Xlib = CDLL("libX11.so.6")
display = Xlib.XOpenDisplay(None)
if display == 0: sys.exit(2)
w = Xlib.XRootWindow(display, c_int(0))
(root_id, child_id) = (c_uint32(), c_uint32())
(root_x, root_y, win_x, win_y) = (c_int(), c_int(), c_int(), c_int())
mask = c_uint()
ret = Xlib.XQueryPointer(display, c_uint32(w), byref(root_id), byref(child_id),
                         byref(root_x), byref(root_y),
                         byref(win_x), byref(win_y), byref(mask))
if ret == 0: sys.exit(1)
print child_id.value

Ejemplo de uso:

xwininfo -tree -id $(XQueryPointer)
Gilles 'SO- deja de ser malvado'
fuente
1
Gracias Gilles: Esto es (casi) exactamente lo que necesito ... Es ideal, pero por el hecho de que devuelve un valor de '0' para el escritorio en sí mismo. Se devuelve una ID de ventana distinta de cero (para el escritorio) por el xdotool click 1método asincrónico mencionado en el comentario a la respuesta de Bruce Ediger . La ID de escritorio que no es cero es válida en la medida en que devuelve la imagen apropiada a través de import -window $nonzeroID screen.png... ¿Hay algún ajuste simple para que el script de Python devuelva ese valor para el escritorio? ?
Peter
@Gilles ... Prueba $(XQueryPointer)de 0, y llamando xwininfo -rootpara esta condición se resuelve esta peculiaridad .. Gracias ..
Peter.O
@fred No probado porque no estoy frente a una máquina Unix: intente imprimir root_id.valuesi child_id.value == 0.
Gilles 'SO- deja de ser malvado'
Sí, tu mod funciona bien .. if child_id.value == 0: print root_id.value else: print child_id.value :)
Peter.O
sed /x[0-9]\\++/q\;d <(xwininfo -tree -id $(XQueryPointer))
F. Hauri
21

El xwininfocomando proporciona este tipo de salida, pero debe hacer clic en la ventana en la que desea información:

% xwininfo
xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0xa0000d "flask"

...

Al hacerlo, xwininfo | grep 'Window id:'podría darte algo de lo que puedes analizar la identificación.

Bruce Ediger
fuente
1
Necesito que sea no interactivo ...
Peter.O
1
Se puede hacer que no sea interactivo ejecutándolo en segundo plano xwinfo |grep window id:' &y siguiéndolo con xdotool click 1... pero eso corre el riesgo de que el primer plano se clickejecute antes de que xdotoolagarre el mouse. Me Rathen no haría uso de un 'sueño nominal n, por lo que aunque esta respuesta es en la pista, voy a esperar un wihile para ver si hay algo más en línea se convierte en imagen ...
Peter.O
8

intente esto, solo usa xdotool, pero su versión es al menos "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

para obtener la identificación de la ventana directamente, puede usar esto:

sedGetValue='s/.*=\(.*\)/\1/'
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId
Poder de acuario
fuente
1
funcionó, gracias, por cierto, esto puede ser útilxdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209
1

xdotool es lo suficientemente bueno como para hacerlo.

Ejecute xdotool getactivewindowy verá el resultado (int) La ventana puede estar sobre CUALQUIER monitor. Simplemente lea dónde está ubicado el puntero x11 esperando un clic :), y no importa si se trata de una ventana remota, un servidor virtual o el tercer escritorio del entorno de escritorio del cubo. Solo funciona

Puedes jugarlo usando sleep para mejores pruebas sleep 3; xdotool click 1+2; xdotool getactivewindow.

He visto que getwindowsfocusdevuelve el mismo valor que getactivewindow.

Si hace los clics manualmente, verá el menú contextual, pero al hacer clic en 1 + 2 se activan ambos clics al mismo tiempo que se hace clic en la ubicación actual del mouse y se obtiene la identificación deseada.

Intentalo :)

m3nda
fuente
1
Esto le da al ID de la ventana activa (donde quiera que la ventana puede ser), independientemente de si o no esa ventana activa está bajo el puntero del ratón. Según la redacción de la pregunta: "... encuentre la ID de la ventana X debajo del puntero del mouse ..." (donde sea que esté ese mouse ).
Peter
1
Gracias por la corrección, tienes razón. Actualizado . Estaba mezclando el concepto de ubicación correcta con ventana activa, pero de todos modos, xdotool es lo suficientemente genial.
m3nda
1

Si tiene acceso a python-xlib , aquí hay un equivalente más corto y más pitónico a la respuesta de Gilles:

from Xlib.display import Display

display = Display()
window = display.screen().root
result = window.query_pointer()

print(result.child.id)
Noé Martínez
fuente
0

Jugué con la respuesta de Peter.O y se me ocurrió:

xdotool click 1|xwininfo|grep 'Window id:'
Ikem Krueger
fuente
1
Eso envía un clic del mouse, por lo que, por ejemplo, haría clic en un botón donde está el cursor del mouse. Incidentalmente, informaría la ventana donde está el cursor si usa clic para enfocar, pero enviar un evento de clic es perjudicial.
Gilles 'SO- deja de ser malvado'
0

ArchWiki tiene una buena respuesta a esto:

activeWinLine=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)")
activeWinId=${activeWinLine:40}

Utilizando sedpuede hacer esto en una sola línea, que es probablemente la forma más legible de hacerlo:

activeWin="$(xprop -root | sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p')"

Tenga en cuenta que xdotoolfaltaba en mi Debian minimal X11 mientras xpropestaba incluido (también, sedpor supuesto).

Si no desea bifurcar sedni greppuede hacer la transformación de texto por completo bash, lo que tal vez sea un poco más seguro en caso de que la salida de xpropcambios cambie un poco:

activeWin="$(xprop -root)"
activeWin="${activeWin#*_NET_ACTIVE_WINDOW(WINDOW):}'
activeWin="${activeWin%%?_NET_*}'
activeWin="${activeWin##* }'

De todos modos, sigue siendo una forma extraña de archivar una tarea tan simple.

Tino
fuente
3
Esto proporciona la ID de la ventana activa en lugar de la ventana debajo del puntero del mouse.
Peter.O
@ Peter.O Tienes razón, esto devuelve la ventana activa. Perdón por la respuesta incorrecta, sin embargo, con mis pruebas funcionó, probablemente porque tenía enfocado-sigue-mouse.
Tino
0
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
azulado
fuente
1
Esto proporciona la ID de la ventana activa en lugar de la ventana debajo del puntero del mouse.
Peter.O
Oh, estaba asumiendo un enfoque descuidado (el enfoque sigue al mouse) aquí.
azulado
@blueyed Focus está en las ventanas activas, y esta ventana responde al TECLADO. X11 sigue / rastrea el mouse desde su servidor, y cuando hace clic en una ventana, x11 establece el foco del administrador de ventanas en ventanas clicadas. El foco no sigue al ratón realmente. Puede verificar correr xdotool getwindowsfocusdesde una consola y mover el mouse. El valor sería el mismo hasta que haga clic con el mouse o interactúe con el teclado (alt + tab, etc.)
m3nda