Est-il possible de déplacer toutes les fenêtres (ou toutes les fenêtres non minimisées) d'un espace de travail à un autre?
Je sais que je peux déplacer une fenêtre vers un autre espace de travail avec Shift+Ctrl+Alt+arrow, mais il ne déplacera que cette fenêtre ciblée.
Unité: Que sont les fenêtres de visualisation?
Ubuntu Unity utilise des fenêtres - un système de coordonnées (la coordonnée 0,0 étant le coin supérieur gauche), dans lequel un bureau géant est subdivisé en morceaux qui correspondent à la résolution de votre écran. Les coordonnées gagnent en valeur lorsque vous vous déplacez vers la droite et vers le bas.
Le système de coordonnées est relatif. Si ma fenêtre d'affichage actuelle est en haut à gauche, tout ce qui le concerne sera des valeurs positives par incréments de largeur et de hauteur. Par exemple, si ma fenêtre d'affichage actuelle est en haut à gauche, la fenêtre firefox située en haut au milieu de l'espace de travail que vous voyez ci-dessus est positionnée à la valeur x 1366 et à la valeur y 0 par rapport à la fenêtre d'affichage la plus à gauche. Si ma fenêtre d'affichage active est en haut au centre, la fenêtre du terminal dans la fenêtre en haut à gauche est positionnée à la valeur x -1327 60. Il s'agit de l'enjeu clé pour xdotool
, car xdotool
ne traite pas les nombres négatifs.
Notez également que xdotool considère toujours le coin supérieur gauche de la fenêtre actuelle comme les coordonnées 0 0. Cela signifie que nous ne pouvons que déplacer les choses à droite et à gauche.
Utiliser xdotool pour Unity
Nous savons maintenant que xdotool
ne peut déplacer les fenêtres que par rapport à notre coin supérieur gauche (c’est-à-dire que vous pouvez toujours déplacer la fenêtre vers le bas et la droite, mais jamais vers le haut et la gauche). Comment faisons-nous ce travail pour l'unité. Eh bien, l’idée de base serait de
Solution de script
Le script ci-dessous effectue exactement la procédure décrite ci-dessus. Il peut être appelé avec le drapeau -v
pour spécifier manuellement les coordonnées ou vous pouvez utiliser le drapeau -g
pour ouvrir la boîte de dialogue de l'interface graphique. Le drapeau -f
indiquera au script de changer de fenêtre d'affichage également; si cet indicateur n'est pas utilisé - vous resterez dans la fenêtre actuelle et seules les fenêtres seront déplacées
Obtention du script
On peut copier le code source de cet article directement ou via github en procédant comme suit:
Sudo apt-get install git
cd /opt ; Sudo git clone https://github.com/SergKolo/sergrep.git
Sudo chmod -R +x sergrep
Le fichier de script sera /opt/sergrep/move_viewport_windows.sh
Pour lier un script à un raccourci, voir Comment lier des fichiers .sh à une combinaison de clavier?
Notez que wmctrl
et xdotool
sont requis pour que ce script fonctionne correctement. Vous pouvez les installer via Sudo apt-get install xdotool et wmctrl
Code source
#!/usr/bin/env bash
#
###########################################################
# Author: Serg Kolo , contact: [email protected]
# Date: April 17 2016
# Purpose: Move all windows on the current viewport
# to a user-defined one
# Written for:
# Tested on: Ubuntu 14.04 LTS , Unity 7.2.6
###########################################################
# Copyright: Serg Kolo , 2016
#
# Permission to use, copy, modify, and distribute this software is hereby granted
# without fee, provided that the copyright notice above and this permission statement
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
get_active_viewport()
{
xprop -root -notype _NET_DESKTOP_VIEWPORT
}
get_screen_geometry()
{
xwininfo -root | awk '/-geometry/{gsub(/+|x/," ");print $2,$3}'
}
current_wins()
{
HEX="$(wmctrl -lG | \
awk -v xlim="$XMAX" -v ylim="$YMAX" \
'BEGIN{printf "ibase=16;"} $3>0 && $3<xlim && $4>0 && $4<ylim \
{ gsub(/0x/,""); printf "%s;",toupper($1) } ')"
echo $HEX | bc | tr '\n' ' '
}
gui_selection()
{
SCHEMA="org.compiz.core:/org/compiz/profiles/unity/plugins/core/"
read swidth sdepth <<< "$(get_screen_geometry)"
vwidth=$(gsettings get $SCHEMA hsize)
vheight=$(gsettings get $SCHEMA vsize)
width=0
for horizontal in $(seq 1 $vwidth); do
height=0
for vertical in $(seq 1 $vheight); do
array+=( FALSE )
array+=( $(echo "$width"x"$height") )
height=$(($height+$sdepth))
done
width=$(($width+$swidth))
done
zenity --list --radiolist --column="" --column "CHOICE" ${array[@]} --width 350 --height 350 2> /dev/null
}
print_usage()
{
cat << EOF
move_viewport_windows.sh [-v 'XPOS YPOS' ] [-g] [-f ] [-h]
Copyright Serg Kolo , 2016
The script gets list of all windows on the current Unity
viewport and moves them to user-specified viewport. If
ran without flags specified, script prints this text
-g flag brings up GUI dialog with list of viewports
-v allows manually specifying viewoport. Argument must be
quoted, X and Y position space separated
-f if set, the viewport will switch to the same one where
windows were sent
-h prints this text
** NOTE **
wmctrl and xdotool are required for this script to work
properly. You can install them via Sudo apt-get install
xdotool and wmctrl
EOF
}
parse_args()
{
if [ $# -eq 0 ];then
print_usage
exit
fi
while getopts "v:ghf" opt
do
case ${opt} in
v) NEWVP=${OPTARG}
;;
g) NEWVP="$(gui_selection | tr 'x' ' ' )"
[ -z "$NEWVP" ] && exit 1
;;
f) FOLLOW=true
;;
h) print_usage
exit 0
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
shift $((OPTIND-1))
}
main()
{
# Basic idea:
#-------------------
# 1. get current viewport and list of windows
# 2. go to viewport 0 0 and move all windows from list
# to desired viewport
# 3. go back to original viewport or follow the windows,
# depending on user choice
# 4. Tell the user where they are currently
local FOLLOW
local NEWVP # coordinates of desired viewport
local XMAX YMAX # must be two vals for awk to work
local OLDVP=$(get_active_viewport | awk -F '=' '{sub(/,/," ");print $2}' )
parse_args "$@"
read XMAX YMAX <<< "$(get_screen_geometry)" # move to getopts
windows=( $(current_wins) )
xdotool set_desktop_viewport 0 0
for win in ${windows[@]} ; do
echo "$win"
xdotool windowmove $win $NEWVP
done
# sleep 0.25 # uncomment if necessary
if [ $FOLLOW ]; then
xdotool set_desktop_viewport $NEWVP
else
xdotool set_desktop_viewport $OLDVP
fi
sleep 0.25 # delay to allow catching active viewport
notify-send "current viewport is $(get_active_viewport | awk -F '=' '{sub(/,/," ");print $2}' )"
exit 0
}
main "$@"
Démo
Enregistrement Webm du script en action:
https://www.youtube.com/watch?v=cJMlC41CWWo
Problèmes
En raison du plug-in grid
de Unity, responsable de l'accrochage des fenêtres, le script ne peut pas déplacer les fenêtres agrandies, ou agrandies à droite ou à gauche. On essaiera d’ajouter l’instantané non défini et la réinitialisation de ce plugin pour que le script fonctionne avec toutes les fenêtres, mais étant donné que la réinitialisation et la réinitialisation prennent du temps, il peut être abandonné en tant qu’idée. Si vous voulez que le script fonctionne avec toutes les fenêtres, installez unity-Tweak-tool
et désactivez l'accrochage de la fenêtre sous les options du Gestionnaire de fenêtres.
Environnements de bureau non basés sur Compiz (XFCE, LXDE, GNOME, KDE ...)
Vous pouvez utiliser une combinaison de wmctrl
et xdotool
pour cela. Assurez-vous d'abord que ces deux utilitaires sont installés:
Sudo apt-get install xdotool wmctrl
Avec les dépendances satisfaites, vous devriez pouvoir utiliser la ligne suivante pour déplacer toutes les fenêtres du bureau actuel vers une autre:
while read i; do wmctrl -i -t 2 -r "$i" ; done < <(wmctrl -l | awk -v var=$(xdotool get_desktop) '{if ($2 == var) print $0;}' | cut -d' ' -f1)
Une ventilation rapide des commandes utilisées:
wmctrl -l | awk -v var=$(xdotool get_desktop) '{if ($2 == var) print $0;}' | cut -d' ' -f1
Répertorie toutes les fenêtres, filtre celles qui ne figurent pas dans l'espace de travail actuel et extrait leur ID de fenêtre.
wmctrl -i -t 2 -r "$i"
Déplacer la fenêtre avec l'ID de fenêtre $i
vers l'espace de travail 2.
tout cela est emballé dans une simple boucle while read ... do; done
qui parcourt toutes les fenêtres du bureau actuel.
Environnements de bureau basés sur Compiz (par exemple, Unity)
Trouver une solution pour des environnements de bureau tels que Unity est rendu difficile par le fait que Compiz (le gestionnaire de fenêtres de Unity) n'utilise pas les ordinateurs de bureau de manière traditionnelle .