Como mover todas as janelas para outro espaço de trabalho

8

É possível mover todas as janelas (ou todas as janelas não minimizadas) de uma área de trabalho para outra?

Eu sei que posso mover uma janela para outro espaço de trabalho com Shift + Ctrl + Alt + seta , mas vai mover apenas aquela janela focada.

    
por betatester07 21.05.2014 / 22:58

2 respostas

5

Unity: o que são Viewports?

O Ubuntu Unity usa viewports - basicamente um sistema de coordenadas (com a coordenada 0,0 sendo o canto superior esquerdo), onde uma área de trabalho gigante é subdividida em blocos que se ajustam à sua resolução de tela. As coordenadas crescem em valor à medida que você se move para a direita e para baixo.

Osistemadecoordenadasérelativo.Seaminhaviewportatualestivernocantosuperioresquerdo,tudoemrelaçãoaessaviewportserávalorespositivosemincrementosdelarguraealtura.Porexemplo,seaminhaviewportatualestivernocantosuperioresquerdo,ajaneladofirefoxnoespaçodetrabalhosuperiorsuperiorquevocêvêacimaéposicionadaemxvalor1366eyvalor0emrelaçãoàviewportsuperioresquerda.Seaminhaviewportativaestivernapartesuperior,ajaneladoterminalnaviewportsuperioràesquerdaéposicionadaemxvalor-132760.Esteéoprincipalproblemaparaxdotool,porquexdotoolnãotratanúmerosnegativos.

Notetambémque,ocantosuperioresquerdodasuaviewportatualserásempreassumidoporxdotoolcomocoordenadas00.Issosignificaquesópodemosmoverascoisasparaadireitaeparabaixo.

FazendooxdotoolfuncionarparaUnity

Agorasabemosquexdotoolpodemoverjanelasapenasemrelaçãoaonossocantosuperioresquerdo(ouseja,vocêsemprepodemoverajanelaparabaixoeparaadireita,masnuncaparacimaeparaaesquerda).Comofazemosessetrabalhopelaunidade?Bem,aideiabásicaseria

  1. Descobrirtodasasjanelasnajaneladevisualizaçãoatual
  2. Mova-separaumajaneladevisualizaçãosolicitadamomentaneamenteparaqueocantosuperioresquerdoassumaascoordenadas00nessajanela
  3. Movertodasasjanelasparacoordenadasdajaneladevisualizaçãodefinidaspelousuário
  4. Retornarparaaviewportantiga(opcional,tambémpodeseguirasjanelas)

Soluçãodescripts

Oscriptabaixoexecutaexatamenteoprocedimentodescritoacima.Elepodeserchamadocom-vflagparaespecificarcoordenadasmanualmenteouvocêpodeusar-gflagparaexibiracaixadediálogodaGUI.-fflagirádizeraoscriptparamudartambémaviewport;seessesinalizadornãoforusado,vocêpermaneceránaviewportatualesomenteasjanelasserãomovidas

Comoobteroscript

Épossívelcopiarocódigo-fontedestapostagemdiretamenteoupormeiodogithub,usandoasseguintesetapas:

  1. sudoapt-getinstallgit
  2. cd/opt;sudogitclonehttps://github.com/SergKolo/sergrep.git
  3. sudochmod-R+xsergrep

Oarquivodescriptserá/opt/sergrep/move_viewport_windows.sh

Paraligaroscriptaoatalho,consulte Como faço para ligar arquivos .sh à combinação de teclado?

Observe que wmctrl e xdotool são necessários para que esse script funcione devidamente. Você pode instalá-los via sudo apt-get install xdotool e wmctrl

Código-fonte

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

Demonstração

Gravação de Webm do script em ação:

link

Problemas

Devido ao plug-in grid do Unity, responsável pelo snap-in da janela, o script não pode mover as janelas maximizadas ou com o clique à direita / esquerda. Será tentado adicionar o momentâneo unset e reset daquele plugin para fazer o script funcionar com todas as janelas, mas como a desfeita e a redefinição têm um atraso de tempo, ele pode ser abandonado como uma idéia. Se você quiser que o script funcione com todas as janelas, instale unity-tweak-tool e não ajuste o ajuste de janela nas opções do Gerenciador de Janelas.

    
por Sergiy Kolodyazhnyy 17.04.2016 / 15:31
3

Ambientes de desktop não baseados em Compiz (XFCE, LXDE, GNOME, KDE ...)

Você pode usar uma combinação de wmctrl e xdotool para isso. Primeiro, verifique se esses dois utilitários estão instalados:

sudo apt-get install xdotool wmctrl

Com as dependências satisfeitas, você deve poder usar o seguinte one-liner para mover todas as janelas da área de trabalho atual para outra:

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)

Um rápido detalhamento dos comandos usados:

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

    Listar todas as janelas, filtrar as que não estão no espaço de trabalho atual e extrair o ID da janela

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

    Mova a janela com a ID da janela $i para a área de trabalho 2.

  • tudo isso é compactado em um loop while read ... do; done simples que é repetido em todas as janelas da área de trabalho atual

Ambientes de área de trabalho baseados em Compiz (por exemplo, Unity)

Encontrar uma solução para ambientes de desktop como o Unity é dificultado pelo fato de que o Compiz (gerenciador de janelas da Unity) não usa desktops em um ambiente tradicional. sentido .

    
por Glutanimate 25.02.2015 / 20:26