Cómo mover todas las ventanas a otro espacio de trabajo

8

¿Es posible mover todas las ventanas (o todas las ventanas no minimizadas) de un espacio de trabajo a otro?

Sé que puedo mover una ventana a otro espacio de trabajo con Shift+ Ctrl+ Alt+ arrow, pero moverá solo esa ventana enfocada.

betatester07
fuente
¿Sigue interesado en una solución de Unity?
Jacob Vlijm
Sí, quería una solución para Unity. lo siento, no especifiqué exactamente que estoy usando Unity
betatester07
¿Notaste este? No lo intenté, no sé si aún funciona. Si no, podría considerar hacer una alternativa bajo una combinación de teclas de acceso directo.
Jacob Vlijm
Ah, lo siento, eso es para una sola ventana, ¡lo miraré!
Jacob Vlijm
He estado trabajando en ello y tengo un "tipo de" script de trabajo. Sin embargo, los problemas que ocurren al azar hacen que sea difícil de usar. lo publicaré si descubro qué lo causa.
Jacob Vlijm

Respuestas:

5

Unidad: ¿Qué son los Viewports?

Ubuntu Unity usa viewports, básicamente un sistema de coordenadas (con la coordenada 0,0 en la esquina superior izquierda), donde un escritorio gigante se subdivide en fragmentos que se ajustan a la resolución de su pantalla. Las coordenadas crecen en valor a medida que se mueve hacia la derecha y hacia abajo.

ingrese la descripción de la imagen aquí

El sistema de coordenadas es relativo. Si mi ventana gráfica actual está en la parte superior izquierda, todo lo relativo a esa ventana gráfica tendrá valores positivos en incrementos de ancho y alto. Por ejemplo, si mi ventana de visualización actual está en la parte superior izquierda, la ventana de Firefox en el espacio de trabajo superior central que ve arriba se coloca en el valor x 1366 y el valor y 0 en relación con la ventana superior izquierda. Si mi ventana activa es la del medio superior, la ventana de terminal en la ventana superior izquierda se coloca en el valor x -1327 60. Este es el tema clave paraxdotool , porque xdotoolno trata con números negativos.

Tenga en cuenta también que la esquina superior izquierda de su ventana gráfica actual siempre será asumida por xdotool como coordenadas 0 0. Eso significa que solo podemos mover cosas de derecha a abajo.

Hacer que xdotool funcione para Unity

Ahora sabemos que xdotoolpuede mover ventanas solo en relación con nuestra esquina superior izquierda (es decir, siempre puede mover ventanas hacia abajo y hacia la derecha, pero nunca hacia arriba y hacia la izquierda). ¿Cómo hacemos que funcione para la unidad? Bueno, la idea básica sería

  1. Descubre todas las ventanas en la ventana gráfica actual
  2. Muévase a una ventana solicitada momentáneamente para que la esquina superior izquierda asuma las coordenadas 0 0 en esa ventana
  3. Mover todas las ventanas a coordenadas de ventana definidas por el usuario
  4. Regrese a la ventana gráfica anterior (opcional, también podría seguir las ventanas)

Solución de secuencias de comandos

El siguiente script realiza exactamente el procedimiento descrito anteriormente. Se puede invocar con una -vmarca para especificar coordenadas manualmente o puede usar una -gmarca para abrir el cuadro de diálogo GUI. -fflag le dirá al script que cambie la ventana gráfica también; si esa bandera no se usa, permanecerá en la ventana gráfica actual y solo se moverán las ventanas

Obteniendo el guión

Se puede copiar el código fuente de esta publicación directamente o mediante github usando los siguientes pasos:

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

El archivo de script será /opt/sergrep/move_viewport_windows.sh

Para enlazar el script al acceso directo, consulte ¿Cómo enlazo archivos .sh a la combinación de teclado?

Tenga en cuenta que wmctrly xdotoolson necesarios para que este script funcione correctamente. Puede instalarlos a través de sudo apt-get install xdotool y wmctrl

Código fuente

#!/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 "$@"

Manifestación

Grabación webm del guión en acción:

https://www.youtube.com/watch?v=cJMlC41CWWo

Cuestiones

Debido al gridcomplemento de Unity que es responsable del ajuste de la ventana, la secuencia de comandos no puede mover las ventanas maximizadas o ajustadas a la derecha / izquierda. Se intentará agregar el desarmado y restablecimiento momentáneo de ese complemento para que el script funcione con todas las ventanas, pero debido a que el desarmado y el restablecimiento tienen un retraso de tiempo, puede ser abandonado como una idea. Si desea que el script funcione con todas las ventanas, instale unity-tweak-tooly desactive el ajuste de ventana en las opciones del Administrador de ventanas.

Sergiy Kolodyazhnyy
fuente
increíble cómo una respuesta dedicada como esta obtiene solo 2-3 votos a favor ...
chiflado sobre natty
3

Entornos de escritorio no basados ​​en Compiz (XFCE, LXDE, GNOME, KDE ...)

Puede usar una combinación de wmctrly xdotoolpara esto. Primero asegúrese de que estas dos utilidades estén instaladas:

sudo apt-get install xdotool wmctrl

Con las dependencias satisfechas, debería poder usar la siguiente línea para mover todas las ventanas del escritorio actual a otra:

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)

Un desglose rápido de los comandos utilizados:

  • wmctrl -l | awk -v var=$(xdotool get_desktop) '{if ($2 == var) print $0;}' | cut -d' ' -f1

    Enumere todas las ventanas, filtre las que no están en el espacio de trabajo actual y extraiga su ID de ventana

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

    Mueva la ventana con ID de ventana $ial espacio de trabajo 2.

  • todo esto está empaquetado en un while read ... do; donebucle simple que itera sobre todas las ventanas en el escritorio actual

Entornos de escritorio basados ​​en Compiz (por ejemplo, Unity)

Encontrar una solución para entornos de escritorio como Unity se dificulta por el hecho de que Compiz (el administrador de ventanas de Unity) no usa escritorios en un sentido tradicional .

Glutanimato
fuente
gracias, se ve bien pero estoy usando Unity y esperaba una solución simple. Pero como mencionó, la solución para Unity sería un poco más difícil
betatester07,
Solo un pequeño comentario, espacio de trabajo 2 en "Mover ventana con ID de ventana $ i al espacio de trabajo 2". es en realidad el tercer espacio de trabajo, no el segundo, ya que el primero comienza con cero. Entonces, si solo tiene dos espacios de trabajo, el script podría parecer que no funciona.
Mohamad Fakih