Come spostare tutte le finestre in un'altra area di lavoro


8

È possibile spostare tutte le finestre (o tutte le finestre non ridotte a icona) da un'area di lavoro a un'altra?

So di poter spostare una finestra in un'altra area di lavoro con Shift+ Ctrl+ Alt+ arrow, ma si sposterà solo quella finestra focalizzata.


Sei ancora interessato a una soluzione Unity?
Jacob Vlijm,

si, volevo una soluzione per Unity. scusa, non ho specificato esattamente che sto usando Unity
betatester07,

Hai notato questo? Non ho provato, non so se funziona ancora. Altrimenti, potrei cercare un'alternativa sotto una combinazione di tasti di scelta rapida.
Jacob Vlijm,

Ah, scusa, è per una singola finestra, ci guarderemo dentro!
Jacob Vlijm,

Ci ho lavorato e ho una "specie di" sceneggiatura funzionante. Tuttavia, i problemi che si verificano in modo casuale lo rendono difficilmente utilizzabile. lo posterò se scoprirò cosa lo provoca.
Jacob Vlijm,

Risposte:


5

Unity: cosa sono i viewport?

Ubuntu Unity usa i viewport - sostanzialmente un sistema di coordinate (con la coordinata 0,0 in alto a sinistra), in cui un desktop gigante suddiviso in blocchi che si adattano alla risoluzione dello schermo. Le coordinate aumentano di valore man mano che ci si sposta verso destra e verso il basso.

inserisci qui la descrizione dell'immagine

Il sistema di coordinate è relativo. Se la mia finestra corrente è in alto a sinistra, tutto ciò che riguarda tale finestra sarà valori positivi in ​​incrementi di larghezza e altezza. Ad esempio, se la mia finestra corrente è in alto a sinistra, la finestra di Firefox nell'area di lavoro in alto al centro che vedi sopra è posizionata sul valore x 1366 e il valore y 0 rispetto alla vista più in alto a sinistra. Se il mio viewport attivo è in alto al centro, la finestra del terminale in alto a sinistra è posizionata al valore x -1327 60. Questo è il problema chiave perxdotool , perché xdotoolnon si occupa di numeri negativi.

Si noti inoltre che l'angolo superiore sinistro della finestra corrente verrà sempre assunto da xdotool come coordinate 0 0. Ciò significa che possiamo solo spostare le cose a destra e in basso.

Far funzionare xdotool per Unity

Ora sappiamo che xdotoolpuò spostare le finestre solo rispetto al nostro angolo in alto a sinistra (cioè, puoi sempre spostare le finestre in basso e a destra, ma mai in alto e a sinistra). Come possiamo farlo funzionare per l'unità. Bene, l'idea di base sarebbe

  1. Capire tutte le finestre nella finestra corrente
  2. Passare momentaneamente alla finestra richiesta per fare in modo che l'angolo in alto a sinistra assuma le coordinate 0 0 in quella finestra
  3. Sposta tutte le finestre in coordinate viewport definite dall'utente
  4. Torna al vecchio viewport (facoltativo, potrebbe seguire anche le finestre)

Soluzione di scripting

Lo script seguente esegue esattamente la procedura sopra descritta. Può essere chiamato con uno dei due -vflag per specificare manualmente le coordinate oppure è possibile utilizzare il -gflag per visualizzare la finestra di dialogo della GUI. -fflag dirà allo script di cambiare anche il viewport; se tale flag non viene utilizzato, rimarrai nella finestra corrente e verranno spostate solo le finestre

Ottenere la sceneggiatura

Si può copiare il codice sorgente da questo post direttamente o tramite github usando i seguenti passi:

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

Il file di script sarà /opt/sergrep/move_viewport_windows.sh

Per associare lo script al collegamento, fare riferimento a Come associare i file .sh alla combinazione di tastiera?

Si noti che wmctrle xdotoolsono necessari per questo script per funzionare correttamente. Puoi installarli tramite sudo apt-get install xdotool e wmctrl

Codice sorgente

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

dimostrazione

Registrazione Webm dello script in azione:

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

Problemi

A causa del gridplug-in di Unity che è responsabile dello snap alla finestra, lo script non può spostare le finestre ingrandite a destra o sinistra. Si tenterà di aggiungere il momentaneo disinserimento e ripristino di quel plugin per far funzionare lo script con tutte le finestre, ma poiché il disinserimento e il ripristino hanno un ritardo, potrebbe essere abbandonato come idea. Se vuoi che lo script funzioni con tutte le finestre, installa unity-tweak-toole disattiva lo snap alla finestra nelle opzioni di Gestione finestre.


Incredibile come una risposta dedicata come questa ottenga solo 2-3 voti ...
folle circa il natty

3

Ambienti desktop non basati su Compiz (XFCE, LXDE, GNOME, KDE ...)

È possibile utilizzare una combinazione di wmctrle xdotoolper questo. Per prima cosa assicurati che queste due utility siano installate:

sudo apt-get install xdotool wmctrl

Con le dipendenze soddisfatte dovresti essere in grado di utilizzare il seguente one-liner per spostare tutte le finestre del desktop corrente su un altro:

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)

Una rapida suddivisione dei comandi utilizzati:

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

    Elenca tutte le finestre, filtra quelle che non si trovano nell'area di lavoro corrente ed estrae il loro ID finestra

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

    Sposta la finestra con l'ID della finestra nell'area $idi lavoro 2.

  • tutto questo è racchiuso in un semplice while read ... do; doneciclo che scorre su tutte le finestre sul desktop corrente

Ambienti desktop basati su Compiz (ad esempio Unity)

Trovare una soluzione per ambienti desktop come Unity è reso difficile dal fatto che Compiz (il gestore delle finestre di Unity) non usa i desktop in senso tradizionale .


grazie, sembra buono. ma sto usando Unity e speravo in qualche soluzione semplice. Ma come hai detto, la soluzione per Unity sarebbe un po 'più difficile
betatester07,

Solo una piccola osservazione, spazio di lavoro 2 in "Sposta finestra con ID finestra $ i nello spazio di lavoro 2." è in realtà il terzo spazio di lavoro, non il secondo, poiché il primo inizia con zero. Quindi, se hai solo due aree di lavoro, lo script potrebbe non funzionare.
Mohamad Fakih,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.