¿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.
¿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.
Respuestas:
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.
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 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 de derecha a 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 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
Solución de secuencias de comandos
El siguiente script realiza exactamente el procedimiento descrito anteriormente. Se puede invocar con una -v
marca para especificar coordenadas manualmente o puede usar una -g
marca para abrir el cuadro de diálogo GUI. -f
flag 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:
sudo apt-get install git
cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
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 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 && $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 grid
complemento 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-tool
y desactive el ajuste de ventana en las opciones del Administrador de ventanas.
Entornos de escritorio no basados en Compiz (XFCE, LXDE, GNOME, KDE ...)
Puede 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 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 $i
al espacio de trabajo 2.
todo esto está empaquetado en un while read ... do; done
bucle 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 .