xdotool: come cercare una finestra per titolo e classe con diversi pattern (simile a AutoHotkey)


10

xdotool ti permette di cercare windows usando il suo sottocomando di ricerca. Devo individuare una finestra con classe "gvim" e titolo contenente la parola "TODO". Come faccio a fare questo?

Cosa ho provato:

  • Puoi farlo xdotool search --name --class, ma accetterebbe solo un modello sia per nome che per titolo.
  • xdotool supporta il concatenamento dei comandi, ma non sono riuscito a trovare un modo per concatenare due chiamate di ricerca: la seconda sostituisce semplicemente la prima.

xdotoolfa schifo ... questa è un'operazione così semplice e non c'è modo di farlo elegantemente.
Yan King Yin,

Risposte:


13

La mia guida di xdotool mi informa che i tuoi due interruttori sono uguali (xdotool versione 3.20150503.1),

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

e come tale non fa nulla. Il mio xdotool fa lo stesso del tuo con la sostituzione dello stack di finestre, quindi l'ho fatto con uno script di shell. Di seguito viene fornito uno script di shell che fa ciò che desideri:

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

Gli asterischi nell'istruzione if sono lì per fare una corrispondenza di sottostringa TODO, in modo che possa verificarsi ovunque nel titolo.


sì, scusa, un errore di stampa, intendevo - nome e - classe. Risolverà ora.
t7ko,

@DS potresti dire perché xdotool search --class "gedit" ora funzionerebbe solo per gedit, ma per qualsiasi altra finestra? Stessa storia con l'utilità xprop.
Gonki,

6

Sono stato in grado di identificare una soluzione breve e unix-way:

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

3

Ecco un'altra soluzione che aderisce al modo UNIX!

A prima vista, non è bello come il tuo, @ 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'

Ma abbi pazienza! C'è un po 'di bellezza nascosta in esso.

Insomma

  1. ha una struttura lineare , anziché una struttura ad albero, come una anziché due dimensioni
  2. utilizza una sintassi della shell più nota .
  3. in realtà risponde alla tua domanda: individua la finestra.

(Se questi punti sono vantaggi dipende dal contesto - ignoriamo questo aspetto * .)

Mostrerò lo stesso codice in un layout più strutturato di seguito, per facilitare la comprensione passo dopo passo.
Ma si noti che il rientro serve a spiegare il comando: non indica l'annidamento o giù di lì, tutto è ancora una pipeline UNIX lineare.

Lo stesso comando, appena diviso dopo le pipe ( |):

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'

Il comando completo, come mostrato sopra, fornisce la posizione dei pixel della gvimfinestra, restituendo le coordinate dei pixel relative all'angolo in alto a sinistra della schermata corrente (possibilmente virtuale) come x,y, come 42,433, o forse -5375,-3809quando si trova sulla prima delle quattro schermate virtuali quattro e quello attuale è da qualche parte in basso sul lato destro.

Per ora, accorcerò il comando per trovare solo un ID finestra X11 - forse è tutto ciò che era effettivamente necessario dall'OP, non sono sicuro:

Pipeline di comandi abbreviata, un comando shell separato su ogni riga:

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

Ora inizia a essere leggibile:

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

Il xdotoolcomando searchviene utilizzato per trovare finestre con la " classe " gvim, tralasciando alcune finestre "interne". Il risultato è elencato come PID'(identificatori di processo).
Per ciascuno PID, ne xargsesegue un altro xdotool search, controllando il "nome" per il nostro modello di esempio TODO- dopo aver verificato il PID.

(Per ogni evenienza: le linee che finiscono in \- chiamate linee di continuazione - devono effettivamente terminare con lo \spazio vuoto e senza prima della nuova riga.)

Ora torniamo al comando originale:

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 rimanente elenca alcuni dettagli sulla finestra, inclusa la posizione. Il sedcomando corrisponde e restituisce solo il x,yvalore della posizione.

Ad esempio, eseguendo il comando in alto sul mio 16 ° schermo virtuale (di 4 per 4), con un "TODO" gvimsullo schermo 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

*) Disclaimer: preferisco il codice di @ t7ko. Un sacco!


Usare --onlyvisibleè bello. Mi ha aiutato con un problema simile. Thunderbird può iniziare con 14 finestre e solo una o due sono sul desktop. Non ho idea di cosa servano gli altri. A proposito, solo i mezzi visibili possono essere visualizzati, non solo mostrati immediatamente sul desktop corrente.
Joe,

1

Risposta breve ed elegante (che utilizza wmctrl):

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

L'ID della finestra risultante è in esadecimale, quindi è necessario convertirlo in decimale (utilizzato da xdotool):

printf "%d\n" $result

Quindi puoi fare qualunque cosa con xdotool .


1
wmctrlil manuale dice che -lnon stampa la classe della finestra, ma solo il titolo; quindi il tuo frammento di codice non risolve il mio problema "cerca per titolo E classe".
t7ko,

1
wmctrl -lxfornisce la classe.
david.perez,
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.