Come trovo l'ID della finestra X sotto il puntatore del mouse in bash?


20

Da uno script bash, c'è un modo per ottenere l'ID della finestra X sotto il puntatore del mouse?

(modifica) Ho bisogno che il processo non sia interattivo.

Risposte:


25

xdotoolespone la posizione del puntatore ( xdotool getmouselocation) e le versioni recenti (dal 2.20110530.1) indicano quale finestra si trova anche in quella posizione . Niente di tutto xwininfo, wmctrlo di versioni precedenti di xdotoolsembrano avere un modo per abbinare una finestra da una posizione di schermo in cui è visibile.

La chiamata alla libreria X sottostante è XQueryPointer(corrispondente a un QueryPointermessaggio). Ecco un semplice script wrapper Python attorno a questa chiamata (usando ctypes). Errore nel controllo ampiamente omesso. Supponiamo che tu stia utilizzando la schermata 0 (se non sapevi che i display potrebbero avere più di una schermata, ignoralo).

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

Esempio di utilizzo:

xwininfo -tree -id $(XQueryPointer)

1
Grazie Gilles: questo è (quasi) esattamente quello di cui ho bisogno ... È l'ideale ma per il fatto che restituisce un valore di '0' per il desktop stesso. Viene restituito un ID finestra diverso da zero (per il desktop) dal xdotool click 1metodo asincrono menzionato nel commento alla risposta di Bruce Ediger . L'ID desktop diverso da zero è valido in quanto restituisce l'immagine appropriata tramite import -window $nonzeroID screen.png.... C'è qualche semplice aggiustamento per lo script Python per restituire quel valore per il desktop ?
Peter

@Gilles ... Test $(XQueryPointer)per 0, e chiamando xwininfo -rootper questa condizione risolve questo capriccio .. Grazie ..
Peter.O

@fred Non testato perché non sono davanti a una macchina unix: prova a stampare root_id.valueif child_id.value == 0.
Gilles 'SO- smetti di essere malvagio' il

Sì, la tua mod funziona bene .. 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

Il xwininfocomando fornisce questo tipo di output, ma devi fare clic sulla finestra in cui vuoi informazioni:

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

xwininfo: Window id: 0xa0000d "flask"

...

Così facendo: xwininfo | grep 'Window id:'potrebbe darti qualcosa da cui è possibile analizzare l'ID.


1
Ho bisogno che sia non interattivo ...
Peter

1
Può essere reso non interattivo eseguendolo in background xwinfo |grep window id:' &e seguendolo da xdotool click 1... ma ciò comporta il rischio che il primo piano venga clickeseguito prima di xdotoolafferrare il mouse. Rathen non userebbe un nominale `sleep n, quindi anche se questa risposta è sulla buona strada, aspetterò un wihile per vedere se qualcosa di più in linea si presenta ...
Peter.O

8

prova questo, usa solo xdotool, ma la sua versione è almeno "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

per ottenere direttamente l'id finestra è possibile utilizzare questo:

sedGetValue='s/.*=\(.*\)/\1/'
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId

1
ha funzionato, grazie BTW questo può essere utilexdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209

1

xdotool è abbastanza buono per farlo.

Esegui xdotool getactivewindowe vedrai il risultato (int) La finestra può essere su QUALSIASI monitor. Basta leggere dove si trova il puntatore x11 in attesa di un clic :) e non importa se si tratta di una finestra remota, un vncserver o il terzo desktop dell'ambiente desktop del cubo. Funziona e basta.

Puoi giocare usando il sonno per test migliori sleep 3; xdotool click 1+2; xdotool getactivewindow.

Ho visto che getwindowsfocusrestituisce lo stesso valore di getactivewindow.

Se esegui i clic manualmente, visualizzerai il menu contestuale, ma fai clic su 1 + 2 attiva entrambi i clic alla volta facendo clic sulla posizione corrente del mouse e ottenendo l'id desiderato.

Provalo :)


1
Ciò fornisce l'ID della finestra attiva (ovunque si trovi quella finestra ), indipendentemente dal fatto che quella finestra attiva si trovi o meno sotto il puntatore del mouse. Secondo il testo della domanda: "... trova l'ID della finestra X sotto il puntatore del mouse ..." (ovunque si trovi quel mouse ).
Peter

1
Grazie per la correzione, hai ragione. Aggiornato . Stavo mescolando il concetto di getmouselocation con activewindow, ma comunque xdotool è abbastanza interessante.
m3nda,

1

Se hai accesso a python-xlib , ecco un equivalente più breve e più pitonico della risposta di Gilles:

from Xlib.display import Display

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

print(result.child.id)

0

Ho giocato con la risposta di Peter.O e ho trovato:

xdotool click 1|xwininfo|grep 'Window id:'

1
Questo invia un clic del mouse, quindi farebbe ad esempio clic su un pulsante in cui si trova il cursore del mouse. Riporterebbe per inciso la finestra in cui si trova il cursore se si utilizza il clic per mettere a fuoco, ma l'invio di un evento di clic è dannoso.
Gilles 'SO- smetti di essere malvagio'

0

ArchWiki ha una buona risposta a questo:

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

Usando sedpuoi farlo in una sola riga, che è probabilmente il modo più leggibile per farlo:

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

Si noti che xdotoolmancava nel mio Debian minimal X11 mentre xpropera incluso (allo stesso modo sedovviamente).

Se non si desidera eseguire il fork, sedgrepè possibile eseguire completamente la trasformazione del testo bash, che forse è un po 'più sicura nel caso in cui l'output delle xpropmodifiche cambi un po':

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

Ad ogni modo, è ancora uno strano modo di archiviare un compito così semplice.


3
Ciò fornisce l'ID della finestra attiva anziché la finestra sotto il puntatore del mouse.
Peter

@ Peter.O Hai ragione, questo restituisce la finestra attiva. Ci scusiamo per la risposta sbagliata, tuttavia con i miei test ha funzionato, probabilmente perché avevo focus-follow-mouse acceso.
Tino,

0
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'

1
Ciò fornisce l'ID della finestra attiva anziché la finestra sotto il puntatore del mouse.
Peter

Oh, stavo assumendo una messa a fuoco sciatta (la messa a fuoco segue il mouse) qui.
azzurrato il

@blueyed Focus è sulle finestre attive e questa finestra risponde a TASTIERA. Il mouse è seguito / monitorato da X11 come server da esso e quando si fa clic su una finestra, x11 imposta lo stato attivo del gestore finestre su finestre cliccate. La messa a fuoco non segue davvero il mouse. Puoi controllare l'esecuzione xdotool getwindowsfocusda una console e spostare il mouse. Il valore sarebbe lo stesso fino a quando non fai clic con il mouse o interagisci con la tastiera (alt + tab, ecc.)
m3nda
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.