introduction
La puissance de xdotool
et wmctrl
sort lorsque vous devez effectuer des manipulations sur les fenêtres, telles que le déplacement ou le redimensionnement. Cependant, je crois fermement que dans le seul but de répertorier les programmes en cours d'exécution et les informations les concernant, xprop
et qdbus
sont deux outils suffisants et l'installation xdotool
et à wmctrl
moins que l'utilisateur ne les souhaite pour des fonctionnalités supplémentaires - est une tâche inutile. Dans cette réponse, je voudrais présenter deux solutions de script avec xprop
et qdbus
.
Notez que je ne suis en aucun cas contre xdotool
ou wmctrl
. Je les ai largement utilisés moi-même, mais je les trouve plus puissants lorsqu'ils sont combinés avec d'autres outils. Voici quelques exemples où je les ai utilisés:
Xprop
Le script ci-dessous utilise uniquement xprop pour extraire la liste des fenêtres actives, filtrer uniquement les vraies fenêtres (pas le type de dock suck comme Unity Launcher ou Unity Panel) et afficher leurs informations:
Démo:
$ bash xprop_windows.sh
XID TYPE TITLE
--------------------------------
56623112| "x-terminal-emulator", "X-terminal-emulator"| "sakura"
81789126| "Navigator", "Firefox"| "Restore Session - Mozilla Firefox"
82002372| "Navigator", "Firefox"| "gui - How do I get a list of running applications by using the command line? - Ask Ubuntu - Mozilla Firefox"
33554444| "gnome-terminal", "Gnome-terminal"| "\"Terminal\""
33554486| "gnome-terminal", "Gnome-terminal"| "\"Terminal\""
Source du script :
get_hex_xids()
{
xprop -root -notype _NET_CLIENT_LIST | \
awk 'BEGIN{printf "ibase=16"}\
{gsub(/\,/," ");for(i=1;i<=NF;i++) \
if ($i~/0x/) printf ";%s",substr(toupper($i),3) }'
}
convert_hex2dec()
{
HEXIDS=$(get_hex_xids)
echo $HEXIDS | bc
}
print_header()
{
printf "%s\t%s\t%s\n" "XID" "TYPE" "TITLE"
printf "%s\n" "--------------------------------"
}
list_info()
{
convert_hex2dec | while read line;
do
TYPE=$( xprop -id $line _NET_WM_WINDOW_TYPE | awk -F '=' '{print $2}' )
if [ $TYPE != "_NET_WM_WINDOW_TYPE_NORMAL" ]; then
continue
fi
CLASS=$(xprop -id $line WM_CLASS | awk -F '=' '{print $2}' )
NAME=$( xprop -id $line _NET_WM_NAME | awk -F '=' '{print $2}' )
printf "\n%s|%s|%s\n" "$line" "$CLASS" "$NAME"
done
}
print_header
list_info
Qdbus
Le code ci-dessous effectue essentiellement la même tâche, mais il filtre d'abord les applications, puis répertorie ses fenêtres enfants et fournit enfin des informations à leur sujet.
Exemple d'exécution:
$ bash ~/bin/qdbus_windows.sh
Name: Terminal
Active :false
Children:
33554486|false|""Terminal""
33554444|false|""Terminal""
--------------
Name: Firefox Web Browser
Active :false
Children:
82002372|false|"gui - How do I get a list of running applications by using the command line? - Ask Ubuntu - Mozilla Firefox"
81789126|false|"Restore Session - Mozilla Firefox"
--------------
Name: MY CUSTOM TERMINAL
Active :true
Children:
56623112|true|"sakura"
--------------
Code lui-même:
#!/bin/bash
get_window_paths()
{
qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.WindowPaths
}
get_running_apps()
{
qdbus org.ayatana.bamf /org/ayatana/bamf/matcher org.ayatana.bamf.matcher.RunningApplications
}
list_children()
{
qdbus org.ayatana.bamf "$1" org.ayatana.bamf.view.Children
}
window_info()
{
for window in "$@" ; do
XID=${window##*/}
TYPE=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.window.WindowType)
NAME="$(qdbus org.ayatana.bamf $window org.ayatana.bamf.view.Name)"
ACTIVE=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.view.IsActive)
MONITOR=$(qdbus org.ayatana.bamf $window org.ayatana.bamf.window.Monitor)
# printf "%s|%s|%s|%s\n" $TYPE $MONITOR $ACTIVE "$NAME"
printf "%s|%s|\"%s\"\n" $XID $ACTIVE "$NAME"
done
}
window_paths=( $( get_window_paths | tr '\n' ' ') )
apps_list=( $( get_running_apps | tr '\n' ' ' ) )
for app in ${apps_list[@]} ; do
#echo $app
printf "Name: "
qdbus org.ayatana.bamf $app org.ayatana.bamf.view.Name
printf "Active :"
qdbus org.ayatana.bamf $app org.ayatana.bamf.view.IsActive
printf "Children:\n"
# list_children $app
windows=( $( list_children $app | tr '\n' ' ' ) )
window_info "${windows[@]}"
printf "%s\n" "--------------"
done
Une commande un peu plus simple mais qui nécessite de filtrer la sortie utilise l'interface dbus de la pile de fenêtres d'Unity. Voici essentiellement une fonction que j'ai dans mon.mkshrc
window_stack()
{
qdbus --literal com.canonical.Unity.WindowStack
/com/canonical/Unity/WindowStack \
com.canonical.Unity.WindowStack.GetWindowStack | \
awk -F '{' '{gsub(/\}|\]|,/,"");gsub(/\[/,"\n");print $2}' | \
awk '!/compiz/&&!/^$/ && $4!="\""$3"\"" { L[n++] = $0 }\
END { while(n--) print L[n] }'
}
Exemple d'exécution:
$ window_stack
Argument: (usbu) 56623112 "x-terminal-emulator" true 0
Argument: (usbu) 82002372 "firefox" false 0
Argument: (usbu) 81789126 "firefox" false 0
Argument: (usbu) 33554486 "gnome-terminal" false 0
Argument: (usbu) 33554444 "gnome-terminal" false 0
Exemples d'utilisation de qdbus: