Hello,
Je reposte ici un souci de bug concernant
xdotool et sa commande
behave . mouse-click.
Il est vieux et encore d'actualité :
https://github.com/jordansissel/xdotool/issues/163J'avais posté ce problème dans un autre sujet (qui a été résolu par contournement pour mon cas précis) :
https://debian-facile.org/viewtopic.php?id=30478Mais bon, cette solution n'était pas si invisible que ça dans certains cas.
Bref, j'ai trouvé une sorte d'alternative à ce bug.
Elle passe par
evtest.
La mise en place de l'alternative est décrite dans le commentaire "
Pré-requis" du script (voir plus bas).
Edit: une version plus légère existe au #5.
J'ai appelé le script "
xdo2" reproduisant le comportement de
xdotool .... beahve . mouse-click ....Son aide :
Usage : xdo2 CMD_XDOTOOL
xdo2 [-fipq] [-b BM] [-e EVENT] CMD_XDOTOOL +N|+@ CMD_XDO2
xdo2 -h
Surcouche de 'xdotool'.
Palie au bug de 'xdotool ... behave . mouse-click ...'.
CMD_XDOTOOL est la ligne de commande xdotool remplissant
le WINDOW STACK sur laquelle la recherche de clic se fera ou
une ligne de commande xdotool n'utilisant pas 'mouse-click'
si utilisée seule.
+N ou +@ remplace le 'behave %x mouse-click'
+N indique le numéro N dans la pile WINDOW STACK
sur lequel la recherche de clic se fera.
+@ indique que la recherche de clic se fera sur toute
la pile WINDOW STACK.
CMD_XDO2 est une ligne de commande xdotool appliquée
après la réussite du 'behave mouse-click'.
$ utilisé dans CMD_XDO2 se refère à la fenêtre cliquée.
@ utilisé dans CMD_XDO2 se refère à toute la pile WINDOW STACK.
%N dans CMD_XDO2 pour rappeler la Nième fenêtre de la pile WINDOW STACK.
$, @ ou %N est obligatoire dans CMD_XDO2 comme argument à toute commande
xdotool se reférant à une fenêtre (option de commande comprise).
Particularité de la commande 'exec' : Ne peut être utilisée qu'une seule fois
dans CMD_XDO2, et doit se terminer par un caractère ; (protégé).
Options :
-h, --help Afficher cette aide et quitter.
-b, --button BM Sélectionner le(s) bouton(s) à prendre en compte.
B peut prendre les valeurs :
L : Bouton de gauche.
R : Bouton de droite.
M : Bouton du milieu (clic molette).
M peut prendre les valeurs :
0 : bouton relâché.
1 : bouton pressé.
BM peut aussi être une liste séparé par une virgule.
Exemple : -b L1,R0
-e, --event N Écouter l'event /dev/input/eventN.
N doit être un nombre ou une liste de nombres
séparés par une virgule. Ex : -e 8,9
Désactive la prise en charge des branchements à chaud.
-f, --force Forcer la prise en charge des branchements à chaud.
Utile qu'avec l'option '-e'.
-i, --ignore Désactiver la prise en charge des branchements à chaud.
Inutile avec l'option '-e'. Ignorée si '-f' est utilisée.
-p, --pile Afficher la pile WINDOW STACK de la commande de recherche.
-q, --quit One-shot : si clic réussi, exécute la commande et quitte.
Par défaut, écoute toutes les souris présentes et celles branchées à chaud.
Par défaut, Bouton Gauche Pressé pris en compte.
Fonctionnalités particulières :
Possibilité d'écrire EOF dans la file des events pour arrêter le script.
2 Méthodes :
- Depuis, un processus enfant, le fd 4 est acessible :
echo EOF >&4
- Depuis l'extérieur, en écrivant dans le fichier /tmp/xdo2_PID_fifo,
où PID est le pid de l'instance de ce script :
echo EOF > /tmp/xdo2_PID_fifo
La variable XDOclic est accessible aux processus enfants et détient la valeur
du bouton cliqué : L0 = bouton gauche relâché, R1 = bouton droit pressé ...
Exemple :
> xdo2 search --name ".*" +@ \
exec --sync bash -c 'echo -n "$(date +%s) : "' \; getwindowname $
1645371388 : Bureau
1645371391 : xfce4-panel
^C>
Nécessités : xdotool, evtest, inotify-tools
20-02-2022 Tawal®©
Et le script :
#!/bin/bash
### Pré-requis :
#
# Nécessite : xdotool (sudo apt install xdotool)
# evtest (sudo apt install evtest)
# inotifywait (sudo apt install inotify-tools)
#
# Puis 2 méthodes au choix :
# 1: Inscrire la commande /usr/bin/evtest dans /etc/sudoers de cette façon : sudo visudo
# nom_user ALL = NOPASSWD: /usr/bin/evtest
# Modifier le script aux lignes 207 et 448 pour ajouter 'sudo' devant 'evtest'
#
# 2: Méthode utilsée dans le script :
# Créer un groupe 'mouse-event' : sudo addgroup mouse-event
# Créer une règle udev : /etc/udev/rules.d/99-MesMouses.rules contenant :
# SUBSYSTEM=="input", SYMLINK=="input/by-path/*event-mouse", GROUP="mouse_event", MODE="0660"
# Ajouter les utilisateurs pouvant utiliser ce script au groupe 'mouse_event' : sudo addgroup user mouse_event
# Actif dès le prochain boot.
# Pour une utilisation immédiate (déconnexion session) : sudo udevadm trigger
### ---
### Protection contre la collision de variables (pas d'accès à l'aide)
readarray -t _XDO_MC_col < <(set | grep "^_XDO_MC_.*=.*$")
if [ "${_XDO_MC_col[*]}" ]
then
echo "${0##*/}: Export de variables interdites"
printf "\t%s\n" "${_XDO_MC_col[@]}"
echo "Vérifiez votre environnement !"
exit 127
fi >&2
### Vérification de la présence des programmes requis
if [ "$1" != "-h" ] && [ "$1" != "--help" ]
then
for _XDO_MC_i in xdotool evtest inotifywait
do
if ! hash "$_XDO_MC_i" 2>/dev/null
then
if [ "$1" = inotifywait ]
then
_XDO_MC_j="inotify-tools"
else
_XDO_MC_j="$_XDO_MC_i"
fi
echo "${0##*/}: Nécessite $_XDO_MC_i (sudo apt install $_XDO_MC_j)."
_XDO_MC_quit="ON"
fi
done
[ "$_XDO_MC_quit" ] && exit 1
fi >&2
### Fonctions
usage ()
{
echo -e "Usage : \E[1m${0##*/} CMD_XDOTOOL"
echo -e " \E[1m${0##*/} [-fipq] [-b BM] [-e EVENT] CMD_XDOTOOL +N|+@ CMD_XDO2\E[0m"
echo -e " \E[1m${0##*/} -h\E[0m"
echo
echo -e "Surcouche de '\E[1mxdotool\E[0m'."
echo -e "Palie au bug de '\E[3mxdotool ... behave . mouse-click ...\E[0m'."
echo -e " \E[1mCMD_XDOTOOL\E[0m est la ligne de commande \E[1mxdotool\E[0m remplissant"
echo -e " le \E[1mWINDOW STACK\E[0m sur laquelle la recherche de clic se fera ou"
echo -e " une ligne de commande \E[1mxdotool\E[0m n'utilisant pas '\E[3mmouse-click\E[0m'"
echo " si utilisée seule."
echo -e " \E[1m+N\E[0m ou \E[1m+@\E[0m remplace le '\E[3mbehave %x mouse-click\E[0m'"
echo -e " \E[1m+N\E[0m indique le numéro \E[1mN\E[0m dans la pile \E[1mWINDOW STACK\E[0m"
echo -e " sur lequel la recherche de clic se fera."
echo -e " \E[1m+@\E[0m indique que la recherche de clic se fera sur toute"
echo -e " la pile \E[1mWINDOW STACK\E[0m."
echo -e " \E[1mCMD_XDO2\E[0m est une ligne de commande \E[1mxdotool\E[0m appliquée"
echo -e " après la réussite du '\E[3mbehave mouse-click\E[0m'."
echo -e " \E[1m$\E[0m utilisé dans \E[1mCMD_XDO2\E[0m se refère à la fenêtre cliquée."
echo -e " \E[1m@\E[0m utilisé dans \E[1mCMD_XDO2\E[0m se refère à toute la pile \E[1mWINDOW STACK\E[0m."
echo -e " \E[1m%N\E[0m dans \E[1mCMD_XDO2\E[0m pour rappeler la \E[1mN\E[0mième fenêtre de la pile \E[1mWINDOW STACK\E[0m."
echo -e " \E[1m$\E[0m, \E[1m@\E[0m ou \E[1m%N\E[0m est obligatoire dans \E[1mCMD_XDO2\E[0m comme argument à toute commande"
echo -e " \E[1mxdotool\E[0m se reférant à une fenêtre (option de commande comprise)."
echo -e " Particularité de la commande '\E[1mexec\E[0m' : Ne peut être utilisée qu'une seule fois"
echo -e " dans \E[1mCMD_XDO2\E[0m, et \E[1mdoit\E[0m se terminer par un caractère \E[1m;\E[0m (protégé)."
echo
echo "Options :"
echo " -h, --help Afficher cette aide et quitter."
echo
echo -e " -b, --button \E[1mBM\E[0m Sélectionner le(s) bouton(s) à prendre en compte."
echo -e " \E[1mB\E[0m peut prendre les valeurs :"
echo -e " \E[1mL\E[0m : Bouton de gauche."
echo -e " \E[1mR\E[0m : Bouton de droite."
echo -e " \E[1mM\E[0m : Bouton du milieu (clic molette)."
echo -e " \E[1mM\E[0m peut prendre les valeurs :"
echo -e " \E[1m0\E[0m : bouton relâché."
echo -e " \E[1m1\E[0m : bouton pressé."
echo -e " \E[1mBM\E[0m peut aussi être une liste séparé par une virgule."
echo " Exemple : -b L1,R0"
echo
echo -e " -e, --event \E[1mN\E[0m Écouter l'event \E[3m/dev/input/event\E[0;1mN\E[0m."
echo -e " \E[1mN\E[0m doit être un nombre ou une liste de nombres"
echo " séparés par une virgule. Ex : -e 8,9"
echo " Désactive la prise en charge des branchements à chaud."
echo
echo " -f, --force Forcer la prise en charge des branchements à chaud."
echo " Utile qu'avec l'option '-e'."
echo
echo " -i, --ignore Désactiver la prise en charge des branchements à chaud."
echo " Inutile avec l'option '-e'. Ignorée si '-f' est utilisée."
echo
echo -e " -p, --pile Afficher la pile \E[1mWINDOW STACK\E[0m de la commande de recherche."
echo
echo " -q, --quit One-shot : si clic réussi, exécute la commande et quitte."
echo
echo "Par défaut, écoute toutes les souris présentes et celles branchées à chaud."
echo "Par défaut, Bouton Gauche Pressé pris en compte."
echo
echo "Fonctionnalités particulières :"
echo -e " Possibilité d'écrire \E[1mEOF\E[0m dans la file des events pour arrêter le script."
echo " 2 Méthodes :"
echo -e " - Depuis, un processus enfant, le \E[1mfd 4\E[0m est acessible :"
echo -e " \E[3mecho EOF >&4\E[0m"
echo -e " - Depuis l'extérieur, en écrivant dans le fichier \E[1m/tmp/${0##*/}_PID_fifo\E[0m,"
echo -e " où \E[1mPID\E[0m est le pid de l'instance de ce script :"
echo -e " \E[3mecho EOF > /tmp/${0##*/}_PID_fifo"
echo -e " La variable \E[1mXDOclic\E[0m est accessible aux processus enfants et détient la valeur"
echo " du bouton cliqué : L0 = bouton gauche relâché, R1 = bouton droit pressé ..."
echo
echo "Exemple :"
echo " > ${0##*/} search --name \".*\" +@ \\ "
echo " exec --sync bash -c 'echo -n \"\$(date +%s) : \"' \; getwindowname $"
echo " 1645371388 : Bureau"
echo " 1645371391 : xfce4-panel"
echo " ^C>"
echo
echo "Nécessités : xdotool, evtest, inotify-tools"
printf "%45s%37s\n" "20-02-2022" "Tawal®©"
exit 0
}
err_opt ()
{ # Utilisation d'option non reconnue et sortie.
echo "${0##*/}: Option non-reconnue : $1"
exit 1
} >&2
err_opt_arg ()
{ # Erreur dans le format de l'argument de l'option '-b' ou '-e'.
echo "${0##*/}: Erreur dans l'argument de l'option '$1' : $2"
exit 1
} >&2
err_form_exec ()
{ # La commande 'exec' dans CMD_XDO2 ne se termine pas par un caractère ;
echo -e "${0##*/}: Un caractère '\E[1m;\E[0m' protégé doit finir la commande '\E[1mexec\E[0m'."
exit 1
} >&2
pids_child ()
{ # Liste les processus enfants du script.
local i T
readarray -t T < <(ps --no-headers --ppid "$1" -o pid)
(("${#T[*]}")) && {
for i in "${T[@]}"
do
pids_child $i # $i not quoted to avoid head blank.
done
echo "${T[@]}"
}
}
exit_trap ()
{ # Action à mener par la capture des signaux TERM HUP INT ABRT QUIT EXIT
kill -15 $(pids_child $$) >/dev/null 2>&1
exec 4>&-
exec 5>&-
rm -f "$1"
}
test_opt_b ()
{ # Vérification du format de l'argument de l'option '-b'.
[[ $1 =~ ^[(L|M|R)(0|1),]*(L|M|R)(0|1)$ ]]
}
test_opt_e ()
{ # Vérification du format de l'argument de l'option '-e'.
[[ $1 =~ ^([[:digit:]]*,)*[[:digit:]]*$ ]]
}
test_form_exec ()
{ # Vérification de la présence de ; pour terminer la commande 'exec'.
local elem
for elem in "$@"
do
if [ "$elem" = ";" ]
then
return 0
fi
done
return 1
}
listen_event ()
{ # Écoute des event souris.
local input
for input in "$@"
do
evtest "$input" &
done
}
###--- (Fin Fonctions)
### Gestion des options :
while getopts :b:e:fhipq-: _XDO_MC_opt
do
case $_XDO_MC_opt in
h) usage
;;
b) test_opt_b "$OPTARG" || err_opt_arg "-b" "$OPTARG"
_XDO_MC_opt_b="$OPTARG"
;;
e) test_opt_e "$OPTARG" || err_opt_arg "-e" "$OPTARG"
_XDO_MC_opt_e="$OPTARG"
_XDO_MC_opt_i="ON" # Activation option -i
;;
f) _XDO_MC_opt_f="ON"
;;
i) _XDO_MC_opt_i="ON"
;;
p) _XDO_MC_opt_p="ON"
;;
q) _XDO_MC_opt_q="ON"
;;
-) case $OPTARG in
help)
usage
;;
button)
test_opt_b ${!OPTIND} || err_opt_arg "-b" ${!OPTIND}
_XDO_MC_opt_b="$OPTARG"
OPTIND=$((++OPTIND))
;;
event)
test_opt_e ${!OPTIND} || err_opt_arg "-e" ${!OPTIND}
_XDO_MC_opt_e="$OPTARG"
_XDO_MC_opt_i="ON" # Activation option -i
OPTIND=$((++OPTIND))
;;
force)
_XDO_MC_opt_f="ON"
;;
ignore)
_XDO_MC_opt_i="ON"
;;
pile)
_XDO_MC_opt_p="ON"
;;
quit)
_XDO_MC_opt_q="ON"
;;
*)
err_opt --${!OPTIND}
;;
esac
;;
*) err_opt -"$OPTARG"
;;
esac
done
shift $((--OPTIND))
### Construction Regex matchant bouton cliqué.
if [ "$_XDO_MC_opt_b" ]
then
readarray -td, _XDO_MC_Buttons < <(echo -n "$_XDO_MC_opt_b")
_XDO_MC_Buttons=( "${_XDO_MC_Buttons[@]//L/BTN_LEFT.*value\ }" )
_XDO_MC_Buttons=( "${_XDO_MC_Buttons[@]//M/BTN_MIDDLE.*value\ }" )
_XDO_MC_Buttons=( "${_XDO_MC_Buttons[@]//R/BTN_RIGHT.*value\ }" )
_XDO_MC_regex="$(IFS="|"; echo "${_XDO_MC_Buttons[*]/%/$}")"
else
_XDO_MC_regex="BTN_LEFT.*value\ 1$"
fi
### Séparation CMD_XDOTOOL et CMD_XDO2 et Séparation de Comm_search en cas d'affichage demandé dans CMD_XDOTOOL.
_XDO_MC_Comm=( "$@" )
for _XDO_MC_i in "${!_XDO_MC_Comm[@]}"
do
if [ "${_XDO_MC_Comm[$_XDO_MC_i]:0:1}" != "+" ]
then
if [ "${_XDO_MC_Comm[$_XDO_MC_i]:0:3}" = "get" ] && \
[[ ! ${_XDO_MC_Comm[$_XDO_MC_i]} =~ ^getactivewindow$|^getwindowfocus$ ]] && \
[ ! "${_XDO_MC_Comm_search[*]}" ]
then
_XDO_MC_Comm_search=( "${_XDO_MC_Comm[@]:0:$_XDO_MC_i}" )
fi
_XDO_MC_Comm_deb[$_XDO_MC_i]="${_XDO_MC_Comm[$_XDO_MC_i]}"
continue
else
_XDO_MC_rais="${_XDO_MC_Comm[$_XDO_MC_i]#+}"
fi
shift $((_XDO_MC_i+1))
break
done
### Commande sans 'mouse-click' (pas d'argument +N ou +@ dans la ligne de commande).
if [ ! "$_XDO_MC_rais" ]
then
xdotool "${_XDO_MC_Comm[@]}"
exit
fi
unset _XDO_MC_Comm
### Commande après clic
_XDO_MC_Comm_fin=( "$@" )
### Tableau des fenêtres trouvées.
if [ "${_XDO_MC_Comm_search[*]}" ]
then
readarray -t _XDO_MC_Fen_Sel < <(xdotool "${_XDO_MC_Comm_search[@]}")
else
readarray -t _XDO_MC_Fen_Sel < <(xdotool "${_XDO_MC_Comm_deb[@]}")
fi
### Séparation CMD_XDO2 si présence 'exec' + Contrôle du format de la commande 'exec' + Affectation des ID fenêtres.
for _XDO_MC_i in "${!_XDO_MC_Comm_fin[@]}"
do
# Affectation ID fenêtre par numéro dans la pile.
if [[ "${_XDO_MC_Comm_fin[$_XDO_MC_i]}" =~ ^%[[:digit:]]*$ ]]
then
_XDO_MC_Comm_fin[$_XDO_MC_i]="${_XDO_MC_Fen_Sel[$((${_XDO_MC_Comm_fin[$_XDO_MC_i]:1}-1))]}"
# Affectation dynamique ID fenêtre cliquée (marqueur §).
elif [ "${_XDO_MC_Comm_fin[$_XDO_MC_i]}" = "$" ]
then
_XDO_MC_Comm_fin[$_XDO_MC_i]="§0"
# Affectation des ID fenêtres de toute la pile.
elif [ "${_XDO_MC_Comm_fin[$_XDO_MC_i]}" = "@" ]
then
_XDO_MC_cmd="${_XDO_MC_Comm_fin[$((i-1))]}"
unset '_XDO_MC_Comm_fin[$((i-1))]' '_XDO_MC_Comm_fin[$i]'
for _XDO_MC_fen in "${_XDO_MC_Fen_Sel[@]}"
do
_XDO_MC_Comm_fin=( "${_XDO_MC_Comm_fin[@]:0:$((_XDO_MC_i-1))}" "$_XDO_MC_cmd" "$_XDO_MC_fen" "${_XDO_MC_Comm_fin[@]:$((_XDO_MC_i-1))}" )
i=$((i+2))
done
# Début commande 'exec'.
elif [ "${_XDO_MC_Comm_fin[$_XDO_MC_i]}" = "exec" ]
then
# Contrôle du format commande 'exec'
test_form_exec "${_XDO_MC_Comm_fin[@]:$_XDO_MC_i}" || err_form_exec
# Séparation Comm_fin1
if [ $((_XDO_MC_i)) -gt 0 ]
then
_XDO_MC_Comm_fin1=( "${_XDO_MC_Comm_fin[@]:0:$((_XDO_MC_i))}" )
fi
_XDO_MC_i=$((_XDO_MC_i+1))
# Séparation commande exec
until [[ "${_XDO_MC_Comm_fin[$_XDO_MC_i]}" = ";" ]]
do
_XDO_MC_exec[$_XDO_MC_i]="${_XDO_MC_Comm_fin[$_XDO_MC_i]}"
_XDO_MC_i=$((_XDO_MC_i+1))
done
_XDO_MC_j="$_XDO_MC_i"
fi
done
# Séparation Comm_fin2.
if [ "${_XDO_MC_exec[*]}" ]
then
_XDO_MC_Comm_fin2=( "${_XDO_MC_Comm_fin[@]:$((_XDO_MC_j+1))}" )
unset _XDO_MC_Comm_fin
fi
### Activation de l'affectation dynamique ID fenêtre cliquée.
if [[ ${_XDO_MC_Comm_fin[*]} =~ " §0 "|" §0"$ ]]
then
_XDO_MC_trait="ON"
else
if [[ ${_XDO_MC_Comm_fin1[*]} =~ " §0 "|" §0"$ ]]
then
_XDO_MC_trait1="ON"
fi
if [[ ${_XDO_MC_Comm_fin2[*]} =~ " §0 "|" §0"$ ]]
then
_XDO_MC_trait2="ON"
fi
fi
### Raison de recherche du clic souris (toutes ou une fenêtre de la pile).
if [ "$_XDO_MC_rais" = "@" ]
then
_XDO_MC_id_window="${_XDO_MC_Fen_Sel[*]}"
else
_XDO_MC_id_window="${_XDO_MC_Fen_Sel[$((--_XDO_MC_rais))]}"
fi
### Events à écouter (option -e), par défaut : toutes les souris + celles branchées à chaud.
# Mise en place d'une pile d'enregistrement des event
_XDO_MC_fifo="/tmp/${0##*/}_$$_fifo"
mkfifo "$_XDO_MC_fifo"
# Ouverture en Lecture/Écriture de la pile
exec 6<>"$_XDO_MC_fifo" 4>"$_XDO_MC_fifo" 5<"$_XDO_MC_fifo" 6>&- # fd 6 fermé, reste fd 4 et fd 5.
# Nettoyage si sortie quelconque. Appel de la fontion exit_trap (voir plus haut).
trap 'exit_trap "$_XDO_MC_fifo"' TERM HUP INT ABRT QUIT EXIT >/dev/null 2>&1
# Enregistrement des event souris dans la file selon l'option '-e'.
if [ "$_XDO_MC_opt_e" ]
then
readarray -td, _XDO_MC_event <<< "$_XDO_MC_opt_e"
readarray -t _XDO_MC_event <<<"${_XDO_MC_event[@]/#/\/dev\/input\/event}"
listen_event "${_XDO_MC_event[@]}"
else
readarray -t _XDO_MC_event < <(realpath /dev/input/by-path/*event-mouse)
listen_event "${_XDO_MC_event[@]}"
fi >&4
# Ajout des nouveaux events souris trouvés (branchement à chaud) selon options '-f' et '-i'.
if [ "$_XDO_MC_opt_f" ] || [ ! "$_XDO_MC_opt_i" ]
then
while read -r
do
if [[ $REPLY =~ event-mouse$ ]]
then
evtest "$(realpath "$REPLY")" &
fi
done < <(inotifywait -qme create --format %w%f /dev/input/by-path) &
fi >&4
###---
### Affichage Commande Recherche (option -p et/ou commande xdotool)
if [ "$_XDO_MC_opt_p" ]
then
printf "%s\n" "${_XDO_MC_Fen_Sel[@]}"
fi
if [ "${_XDO_MC_Comm_search[*]}" ]
then
xdotool "${_XDO_MC_Comm_deb[@]}"
fi
### Test en continu du clic souris et exécution de la commande après clic.
shopt -s extglob # Pour la subsitution dans l'ajout de l'ID fenêtre cliquée.
while read -r <&5
do
if [ "$REPLY" = "EOF" ] # Possibilité d'écrire "EOF" dans la file pour arrêter le script :
then # echo "EOF" > /tmp/Nom_PID_fifo avec nom=nom_de_ce_script et PID=pid_de_ce_script
_XDO_MC_retour=99 # Descripteur fd/4 accessible aux processus enfants :
break # echo "EOF" >&4
fi
# Détection du clic souris
if [[ $REPLY =~ $_XDO_MC_regex ]]
then
_XDO_MC_wc=$(xdotool getmouselocation | awk -F: '{printf $NF}')
export XDOclic="${BASH_REMATCH[0]:4:1}${BASH_REMATCH[0]:$((${#BASH_REMATCH[0]}-1)):1}"
### Évite le clic menu contextuel
if [ "$_XDO_MC_wc" = "0" ]
then
continue
fi
# Match l'ID de la fenêtre cliquée
if [[ $_XDO_MC_id_window =~ " $_XDO_MC_wc "|^"$_XDO_MC_wc "|" $_XDO_MC_wc"$|^$_XDO_MC_wc$ ]]
then
# Ajout de l'ID fenêtre cliquée dans les commandes le demandant (marqueur §).
if [ "$_XDO_MC_trait" ]
then
_XDO_MC_Comm_fin=( "${_XDO_MC_Comm_fin[@]//§[[:digit:]]*/§$_XDO_MC_wc}" )
else
if [ "$_XDO_MC_trait1" ]
then
_XDO_MC_Comm_fin1=( "${_XDO_MC_Comm_fin1[@]//§[[:digit:]]*/§$_XDO_MC_wc}" )
fi
if [ "$_XDO_MC_trait2" ]
then
_XDO_MC_Comm_fin2=( "${_XDO_MC_Comm_fin2[@]//§[[:digit:]]*/§$_XDO_MC_wc}" )
fi
fi
# Exécution de la commande après clic.
if [ "${_XDO_MC_exec[*]}" ]
then
if [ "${_XDO_MC_Comm_fin1[*]}" ]
then
xdotool "${_XDO_MC_Comm_fin1[@]#§}"
fi
xdotool exec "${_XDO_MC_exec[@]}"
_XDO_MC_retour=$?
if [ "$_XDO_MC_retour" -gt 0 ]
then
if [ "$_XDO_MC_opt_q" ]
then
break
fi
continue
fi
if [ "${_XDO_MC_Comm_fin2[*]}" ]
then
xdotool "${_XDO_MC_Comm_fin2[@]#§}"
_XDO_MC_retour=$?
fi
else
xdotool "${_XDO_MC_Comm_fin[@]#§}"
_XDO_MC_retour=$?
fi
# One-shot or not ?
if [ "$_XDO_MC_opt_q" ]
then
break
fi
fi
fi
done
exit $_XDO_MC_retour
Edit: Pour copier un si grand script, sélectionner la première ligne (le shebang), descendre tout en bas du script avec l'ascenseur, placer la souris derrière le dernier caractère de la dernière ligne, maintenir enfoncé la touche SHIFT et cliquer (bouton gauche) : tout est sélectionné
Retour d'un exemple (compliqué ) :
xdo2 -p search --name "conky" getwindowname %@ +@ exec --sync bash -c 'echo -n "Le $(date), $USER a cliqué sur "' \; getwindowname $
54525953
50331650
31457282
conky_images
conky_titre
conky_total
Le dim. 13 févr. 2022 09:07:59 CET, tawal a cliqué sur conky_total
Le dim. 13 févr. 2022 09:08:00 CET, tawal a cliqué sur conky_titre
^C
Bon, on comprend sur quoi j'ai cliqué
Décomposition de la commande :
-p : Option affichant la pile WINDOW STACK (les 3 premières lignes du retour = id des fenêtres trouvées).
search --name "conky" getwindowname %@ : CMD_XDOTOOL avec affichage des noms de fenêtres trouvées.
+@ : Recherche de clic sur toute la pile WINDOW STACK
exec --sync bash -c 'echo -n "Le $(date), $USER a cliqué sur "' \; getwindowname $ : CMD_XDO2 commande à exécuter si clic réussi.
la commande exec se termine par \;.
le $ du dernier getwindowname se réfère à l'id de la fenêtre cliquée.
Edit:
Mise à jour importante.
Corrections des bugs, mise au point, ajout d'options.
Edit2:
Mise à jour du script.
Prise en charge des souris branchées à chaud (si l'option -e n'est pas utilisée évidemment)
Ajout du test de présence des programmes requis (xdotool, evtest et inotifywait)
Edit3:
Mise à jour finale du script.
Ré-écriture et restructuration du script.
Mise au propre des fonctions (ne touchent plus directement aux variables globales).
Ajout d'options (-f et -i)
Mise à jour de l'aide.
Dernière modification par Tawal (01-03-2022 15:07:04)
Comme la science n'est pas infuse, elle se diffuse.
Useless Use of Cat Award
Filenames and Pathnames in Shell: How to do it Correctly
À chaque problème sa solution, à chaque solution son moyen, si pas de moyen, toujours le problème !