Comment déplacer toutes les fenêtres vers un autre espace de travail

8

Est-il possible de déplacer toutes les fenêtres (ou toutes les fenêtres non réduites) 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 cela ne déplacera que cette fenêtre focalisée.

betatester07
la source
Êtes-vous toujours intéressé par une solution Unity?
Jacob Vlijm
oui, je voulais une solution pour Unity. désolé, je n'ai pas précisé exactement que j'utilise Unity
betatester07
Avez-vous remarqué celui-ci? Je n'ai pas essayé, je ne sais pas si ça marche toujours. Sinon, je pourrais chercher à faire une alternative sous une combinaison de touches de raccourci.
Jacob Vlijm
Ah, désolé, c'est pour une seule fenêtre, va y jeter un œil!
Jacob Vlijm
J'ai travaillé dessus et j'ai un "genre" de script de travail. Cependant, des problèmes aléatoires le rendent difficilement utilisable. le publiera si je découvre les causes.
Jacob Vlijm

Réponses:

5

Unity: Que sont les fenêtres?

Ubuntu Unity utilise des fenêtres - essentiellement un système de coordonnées (avec la coordonnée 0,0 étant le coin supérieur gauche), où un bureau géant se subdivise 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.

entrez la description de l'image ici

Le système de coordonnées est relatif. Si ma fenêtre actuelle est en haut à gauche, tout ce qui concerne cette fenêtre sera des valeurs positives par incréments de largeur et de hauteur. Par exemple, si ma fenêtre actuelle est en haut à gauche, la fenêtre Firefox dans l'espace de travail du milieu supérieur que vous voyez ci-dessus est positionnée à la valeur x 1366 et à la valeur y 0 par rapport à la fenêtre supérieure la plus à gauche. Si ma fenêtre active est en haut au milieu, la fenêtre du terminal dans la fenêtre en haut à gauche est positionnée à la valeur x -1327 60. C'est le problème clé pourxdotool , car xdotoolil ne traite pas des nombres négatifs.

Notez également que le coin supérieur gauche de votre fenêtre actuelle sera toujours assumé par xdotool comme coordonnées 0 0. Cela signifie que nous ne pouvons déplacer les choses que de droite à droite.

Faire fonctionner xdotool pour Unity

Maintenant, nous savons que les xdotoolfenêtres ne peuvent être déplacées que par rapport à notre coin supérieur gauche (c'est-à-dire que vous pouvez toujours déplacer les fenêtres vers le bas et la droite, mais jamais vers le haut et la gauche). Comment pouvons-nous faire en sorte que cela fonctionne pour l'unité. Eh bien, l'idée de base serait de

  1. Comprendre toutes les fenêtres de la fenêtre courante
  2. Déplacer momentanément vers une fenêtre demandée pour que le coin supérieur gauche assume les coordonnées 0 0 dans cette fenêtre
  3. Déplacer toutes les fenêtres vers les coordonnées de la fenêtre définies par l'utilisateur
  4. Retour à l'ancienne fenêtre (facultatif, pourrait également suivre les fenêtres)

Solution de script

Le script ci-dessous exécute exactement la procédure décrite ci-dessus. Il peut être appelé avec l'un des -vdrapeaux pour spécifier manuellement les coordonnées ou vous pouvez utiliser le -gdrapeau pour afficher la boîte de dialogue de l'interface graphique. -fflag indiquera également au script de changer de fenêtre; si ce drapeau n'est pas utilisé - vous resterez sur la fenêtre courante et seules les fenêtres seront déplacées

Obtention du script

On peut copier le code source de ce post directement ou via github en utilisant les étapes suivantes:

  1. sudo apt-get install git
  2. cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
  3. sudo chmod -R +x sergrep

Le fichier de script sera /opt/sergrep/move_viewport_windows.sh

Pour lier le script au raccourci, reportez-vous à Comment lier des fichiers .sh à une combinaison de touches?

Notez que wmctrlet xdotoolsont 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 gridplugin d'Unity qui est responsable de l'alignement des fenêtres, le script ne peut pas déplacer les fenêtres agrandies ou les fenêtres alignées droite / gauche. Il sera tenté d'ajouter le désarmement et la réinitialisation momentanés de ce plugin pour que le script fonctionne avec toutes les fenêtres, mais comme la réinitialisation et la réinitialisation ont un délai, elle pourrait être abandonnée en tant qu'idée. Si vous souhaitez que le script fonctionne avec toutes les fenêtres, installez unity-tweak-toolet désactivez l'accrochage aux fenêtres sous les options du gestionnaire de fenêtres.

Sergiy Kolodyazhnyy
la source
incroyable de voir comment une réponse dédiée comme celle-ci n'obtient que 2-3 votes positifs ...
about natty
3

Environnements de bureau non basés sur Compiz (XFCE, LXDE, GNOME, KDE ...)

Vous pouvez utiliser une combinaison de wmctrlet xdotoolpour cela. Assurez-vous d'abord que ces deux utilitaires sont installés:

sudo apt-get install xdotool wmctrl

Une fois les dépendances satisfaites, vous devriez pouvoir utiliser le one-liner suivant pour déplacer toutes les fenêtres du bureau actuel vers un 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

    Lister toutes les fenêtres, filtrer celles qui ne se trouvent pas dans l'espace de travail actuel et extraire leur ID de fenêtre

  • wmctrl -i -t 2 -r "$i"

    Déplacer la fenêtre avec l'ID de fenêtre $ivers l'espace de travail 2.

  • tout cela est emballé dans une while read ... do; doneboucle simple qui itère sur toutes les fenêtres du bureau actuel

Environnements de bureau basés sur Compiz (par exemple Unity)

Trouver une solution pour les environnements de bureau comme Unity est rendu difficile par le fait que Compiz (le gestionnaire de fenêtres d'Unity) n'utilise pas les bureaux dans un sens traditionnel .

Glutanimate
la source
merci, ça a l'air bien. mais j'utilise Unity et espérais une solution simple. Mais comme vous l'avez mentionné, la solution pour Unity serait un peu plus difficile
betatester07
Juste une petite remarque, l'espace de travail 2 dans "Déplacer la fenêtre avec l'ID de fenêtre $ i vers l'espace de travail 2." est en fait le troisième espace de travail, pas le second, car le premier commence par zéro. Donc, si vous n'avez que deux espaces de travail, le script peut sembler ne pas fonctionner.
Mohamad Fakih