xdotool: comment rechercher une fenêtre par titre et classe avec différents modèles (similaire à AutoHotkey)

10

xdotool vous permet de rechercher des fenêtres à l'aide de sa sous-commande de recherche. J'ai besoin de localiser une fenêtre, qui a la classe 'gvim' et le titre contenant le mot 'TODO'. Comment puis-je faire cela?

Ce que j'ai essayé:

  • Vous pouvez le faire xdotool search --name --class, mais il n'accepterait qu'un seul modèle pour le nom et le titre.
  • xdotool prend en charge le chaînage de commandes, mais je n'ai pas trouvé de moyen de chaîner deux appels de recherche - le second remplace simplement le premier.
t7ko
la source
xdotoolsuce ... c'est une opération si simple et il n'y a aucun moyen de le faire avec élégance.
Yan King Yin

Réponses:

13

Mon aide xdotool m'informe que vos deux commutateurs sont identiques (xdotool version 3.20150503.1),

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

et en tant que tel ne fait rien. Mon xdotool fait la même chose que la vôtre en remplaçant la pile de fenêtres, donc je l'ai fait avec un script shell. Un script shell faisant ce que vous voulez est fourni ci-dessous:

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

Les astérisques de l'instruction if sont là afin de faire une correspondance de sous-chaîne pour TODOqu'elle puisse apparaître n'importe où dans le titre.

DS
la source
oui, désolé, une faute de frappe, je voulais dire --nom et --classe. Fixera maintenant.
t7ko
@DS pouvez-vous dire pourquoi xdotool search --class "gedit" ne fonctionnerait désormais que pour gedit, mais fonctionnerait pour toute autre fenêtre? Même histoire avec l'utilitaire xprop.
Gonki
6

J'ai pu identifier une solution courte et unix:

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

Voici une autre solution adhérant à la méthode UNIX!

À première vue, il n'est pas aussi beau que le vôtre, @ 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'

Mais supporte-moi! Il y a une beauté cachée en elle.

Bref, il

  1. a une structure linéaire , au lieu d'une structure arborescente, comme une au lieu de deux dimensions
  2. utilise une syntaxe shell plus connue .
  3. répond en fait à votre question: il localise la fenêtre.

(Que ces points soient des avantages dépend du contexte - ignorons simplement cet aspect * .)

Je vais montrer le même code dans une mise en page plus structurée ci-dessous, pour faciliter la compréhension étape par étape.
Mais notez que l'indentation est d'expliquer la commande - elle n'indique pas l'imbrication ou tout, tout est toujours un pipeline UNIX linéaire.

La même commande, juste divisée après les pipes ( |):

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 commande complète, comme indiqué ci-dessus, donne l'emplacement des pixels de la gvimfenêtre, renvoyant les coordonnées des pixels par rapport au coin supérieur gauche de l'écran actuel (éventuellement virtuel) comme x,y, comme 42,433, ou peut -5375,-3809- être quand il se trouve sur le premier des quatre à quatre écrans virtuels et l'actuel se trouve quelque part sur le côté droit.

Pour l'instant, je raccourcirai la commande pour ne trouver qu'un ID de fenêtre X11 - c'est peut-être tout ce dont avait réellement besoin l'OP, pas sûr:

Le pipeline de commandes raccourci, une commande shell distincte sur chaque ligne:

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

Maintenant, il commence à être lisible:

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

La xdotoolcommande searchest utilisée pour rechercher des fenêtres avec la " classe " gvim, en laissant de côté certaines fenêtres "internes". Le résultat est répertorié comme PID'(identificateurs de processus).
Pour chacun PID, en xargsexécute un autre xdotool search, en vérifiant le "nom" pour notre exemple de modèle TODO- après avoir vérifié le PID.

(Juste au cas où: les lignes se terminant par \- appelées lignes de continuation - doivent en fait se terminer par un \et aucun espace avant la nouvelle ligne.)

Revenons maintenant à la commande d'origine:

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 partie restante répertorie certains détails sur la fenêtre, y compris la position. La sedcommande correspond et renvoie uniquement la x,yvaleur de position.

Par exemple, exécuter la commande en haut sur mon 16ème écran virtuel (de 4 par 4), avec un "TODO" gvimsur l'écran 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

*) Avertissement: je préfère le code de @ t7ko. Beaucoup!

Volker Siegel
la source
L'utilisation --onlyvisibleest agréable. M'a aidé avec un problème similaire. Thunderbird peut démarrer avec 14 fenêtres et seulement une ou deux sont sur le bureau. Je ne sais pas à quoi servent les autres. BTW seuls les moyens visibles peuvent être affichés - pas seulement immédiatement affichés sur le bureau actuel.
Joe
1

Réponse courte et élégante (qui utilise wmctrl):

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

L'ID de fenêtre résultant est en hexadécimal, vous devez donc le convertir en décimal (utilisé par xdotool):

printf "%d\n" $result

Ensuite, vous pouvez faire quoi que ce soit avec xdotool.

Yan King Yin
la source
1
wmctrlle manuel indique qu'il -ln'imprime pas la classe de fenêtre, seulement le titre; donc votre extrait de code ne résout pas mon problème "recherche par titre ET classe".
t7ko
1
wmctrl -lxne fournit la classe.
david.perez