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

¿Es posible mover todas las ventanas (o todas las ventanas no minimizadas) desde un área de trabajo a otra?

Sé que puedo mover una ventana a otra área de trabajo con Shift + Ctrl + Alt + flecha , pero solo moverá esa ventana enfocada.

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 partes que se ajustan a la resolución de su pantalla. Las coordenadas crecen en valor a medida que te mueves hacia la derecha y hacia abajo.

introduzca 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 será de valores positivos en incrementos de ancho y alto. Por ejemplo, si mi ventana gráfica actual se encuentra en la parte superior izquierda, la ventana de Firefox en el espacio de trabajo medio superior que se ve arriba se ubica en el valor x 1366 y el valor de y 0 en relación con la ventana superior izquierda. Si mi viewport activo es superior medio, la ventana de terminal en el viewport superior a la izquierda se ubica en el valor x -1327 60. Este es el problema clave para xdotool , porque xdotool no 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 hacia la derecha y hacia abajo.

Hacer que xdotool funcione para Unity

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

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

Solución de Scripting

El siguiente script realiza exactamente el procedimiento descrito anteriormente. Se puede llamar con el indicador -v para especificar coordenadas manualmente o puede usar el indicador -g para abrir el cuadro de diálogo GUI. -f bandera 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 guion

Uno puede copiar el código fuente de esta publicación directamente o a través de 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 la secuencia de comandos al acceso directo, consulte ¿Cómo vinculo los archivos .sh a la combinación del teclado?

Tenga en cuenta que wmctrl y xdotool son 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: 1047481448@qq.com # 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 && $30 && $4 /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 script en acción:

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

Cuestiones

Debido al complemento de grid de Unity que se encarga de ajustar la ventana, el script no puede mover las ventanas maximizadas o las ventanas ajustadas a la derecha / izquierda. Se intentará agregar la desactivación y el restablecimiento momentáneos de ese complemento para hacer que el script funcione con todas las ventanas, pero debido a que el restablecimiento y la reinicialización tienen un retraso de tiempo, podría abandonarse como una idea. Si desea que la secuencia de comandos funcione con todas las ventanas, instale unity-tweak-tool y anule el unity-tweak-tool ventana en las opciones del Administrador de ventanas.

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

Puedes usar una combinación de wmctrl y xdotool para 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 de una 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 rápido desglose 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 área de trabajo actual y extraiga su ID de ventana

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

    Mueva la ventana con la ID de ventana $i al área de trabajo 2.

  • todo esto está empaquetado en un simple while read ... do; done bucle while read ... do; done que recorre todas las ventanas del escritorio actual

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

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