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 um espaço de trabalho para outro?

Sei que posso mover uma janela para outra área de trabalho com Shift+ Ctrl+ Alt+ arrow, mas ela moverá apenas essa janela focada.

betatester07
fonte
Você ainda está interessado em uma solução Unity?
Jacob Vlijm
sim, eu queria solução para o Unity. desculpe, eu didnt exatamente especificar que estou usando Unity
betatester07
Você notou este? Não tentei, não sei se ainda funciona. Caso contrário, eu poderia procurar uma alternativa em uma combinação de teclas de atalho.
Jacob Vlijm
Ah, desculpe, isso é para uma única janela, vai olhar para ela!
Jacob Vlijm
Estão trabalhando nisso e têm um "tipo de" script de trabalho. No entanto, problemas que ocorrem aleatoriamente dificultam o uso. irá publicá-lo se eu descobrir o que o causa.
Jacob Vlijm

Respostas:

5

Unidade: 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 partes que se ajustam à sua resolução de tela. As coordenadas crescem em valor à medida que você se move para a direita e para baixo.

insira a descrição da imagem aqui

O sistema de coordenadas é relativo. Se minha viewport atual estiver no canto superior esquerdo, tudo em relação a essa viewport terá valores positivos em incrementos de largura e altura. Por exemplo, se minha viewport atual estiver no canto superior esquerdo, a janela do firefox na área de trabalho intermediária que você vê acima será posicionada nos valores x 1366 e y 0, em relação à viewport superior à esquerda. Se minha viewport ativa for a principal do meio, a janela do terminal na viewport superior esquerda estará posicionada no valor x -1327 60. Esse é o principal problemaxdotool , porque xdotoolnão lida com números negativos.

Observe também que o canto superior esquerdo da sua viewport atual será sempre assumido pelo xdotool como coordenadas 0 0. Isso significa que só podemos mover as coisas para a direita e para baixo.

Fazendo o xdotool funcionar para o Unity

Agora sabemos que só xdotoolpodemos mover janelas em relação ao canto superior esquerdo (ou seja, você sempre pode mover a janela para baixo e para a direita, mas nunca para cima e para a esquerda). Como fazemos isso funcionar pela unidade. Bem, a ideia básica seria

  1. Descobrir todas as janelas na viewport atual
  2. Mova-se momentaneamente para uma viewport solicitada para que o canto superior esquerdo assuma as coordenadas 0 0 nessa viewport
  3. Mover todas as janelas para coordenadas da janela de visualização definidas pelo usuário
  4. Retorne à janela de exibição antiga (opcional, também pode seguir as janelas)

Solução de script

O script abaixo executa exatamente o procedimento descrito acima. Pode ser chamado com qualquer -vsinalizador para especificar manualmente as coordenadas ou você pode usar o -gsinalizador para abrir o diálogo da GUI. -fflag dirá ao script para mudar a viewport também; se esse sinalizador não for usado - você permanecerá na janela atual e apenas as janelas serão movidas

Obtendo o Script

Pode-se copiar o código fonte desta postagem diretamente ou através do github usando as seguintes etapas:

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

O arquivo de script será /opt/sergrep/move_viewport_windows.sh

Para vincular o script ao atalho, consulte Como vincular arquivos .sh à combinação de teclado?

Observe que wmctrle xdotoolsão necessários para que esse script funcione corretamente. 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 "$@"

Demo

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

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

Problemas

Devido ao gridplug-in do Unity, responsável pelo encaixe da janela, o script não pode mover as janelas maximizadas ou encaixadas à direita / esquerda. Será tentada adicionar a redefinição momentânea e a redefinição desse plug-in para que o script funcione com todas as janelas, mas como a redefinição e redefinição tem um atraso de tempo, ela pode ser abandonada como uma idéia. Se você deseja que o script funcione com todas as janelas, instale unity-tweak-toole desative o snap da janela nas opções do Gerenciador de Janelas.

Sergiy Kolodyazhnyy
fonte
incrível como uma resposta dedicado como este recebe apenas 2-3 upvotes ...
noz sobre natty
3

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

Você pode usar uma combinação de wmctrle xdotoolpara isso. Primeiro verifique se esses dois utilitários estão instalados:

sudo apt-get install xdotool wmctrl

Com as dependências satisfeitas, você poderá usar o seguinte alinhamento para mover todas as janelas da área de trabalho atual para outro:

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)

Uma rápida descrição dos comandos utilizados:

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

    Liste todas as janelas, filtre as que não estão no espaço de trabalho atual e extraia o ID da janela

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

    Mova a janela com o ID da janela $ipara a área de trabalho 2.

  • tudo isso é compactado em um while read ... do; doneloop simples que itera sobre todas as janelas na área de trabalho atual

Ambientes de desktop baseados em Compiz (por exemplo, Unity)

Encontrar uma solução para ambientes de desktop como o Unity é dificultado pelo fato de o Compiz (gerenciador de janelas do Unity) não usar desktops no sentido tradicional .

Glutanimado
fonte
obrigado, parece bom. mas estou usando o Unity e esperava uma solução simples. Mas, como você mencionou, a solução para a Unidade seria um difícil pouco mais
betatester07
Apenas uma pequena observação, espaço de trabalho 2 em "Mover janela com o ID da janela $ i para o espaço de trabalho 2." é realmente o terceiro espaço de trabalho, não o segundo, pois o primeiro começa com zero. Portanto, se você tiver apenas dois espaços de trabalho, o script poderá parecer que não está funcionando.
Mohamad Fakih