Jak przenieść wszystkie okna do innego obszaru roboczego

8

Czy można przenieść wszystkie okna (lub wszystkie niezminimalizowane okna) z jednego obszaru roboczego do drugiego?

Wiem, że mogę przenieść jedno okno do innego obszaru roboczego za pomocą Shift+ Ctrl+ Alt+ arrow, ale przeniesie ono tylko to jedno skoncentrowane okno.

betatester07
źródło
Czy nadal interesuje Cię rozwiązanie Unity?
Jacob Vlijm,
tak, chciałem rozwiązania dla Unity. przepraszam, nie
podałem
Zauważyłeś to? Nie próbowałem, nie wiem, czy to nadal działa. Jeśli nie, mógłbym znaleźć alternatywę w kombinacji klawiszy skrótu.
Jacob Vlijm,
Ach, przepraszam, to dotyczy jednego okna, zajrzę do niego!
Jacob Vlijm,
Pracowałem nad tym i mam „rodzaj” działającego skryptu. Jednak losowo występujące problemy sprawiają, że jest to mało użyteczne. opublikuję, jeśli dowiem się, co go powoduje.
Jacob Vlijm

Odpowiedzi:

5

Jedność: czym są rzutnie?

Ubuntu Unity używa rzutni - w zasadzie układu współrzędnych (gdzie współrzędna 0,0 to lewy górny róg), gdzie jeden gigantyczny pulpit podzielony jest na części pasujące do rozdzielczości ekranu. Współrzędne rosną w miarę przesuwania się w prawo i w dół.

wprowadź opis zdjęcia tutaj

Układ współrzędnych jest względny. Jeśli moja bieżąca rzutnia znajduje się w lewym górnym rogu, wszystko względem tej rzutni będzie dodatnie w przyrostach szerokości i wysokości. Na przykład, jeśli moja bieżąca rzutnia znajduje się w lewym górnym rogu, okno firefox w górnym środkowym obszarze roboczym, które widzisz powyżej, jest ustawione na wartość x 1366 i wartość y 0 względem górnej lewej rzutni. Jeśli moja aktywna rzutnia jest w górnej środkowej, okno terminala w górnej lewej rzutni jest ustawione na wartość x -1327 60. Jest to kluczowa kwestiaxdotool , ponieważ xdotoolnie dotyczy liczb ujemnych.

Zauważ też, że lewy górny róg twojej bieżącej rzutni zawsze będzie przyjmowany przez xdotool jako współrzędne 0 0. Oznacza to, że możemy przesuwać rzeczy tylko w prawo i w dół.

Sprawienie, by xdotool działał dla Unity

Teraz wiemy, że xdotoolmożna przesuwać okna tylko w stosunku do naszego lewego górnego rogu (tzn. Zawsze możesz przesuwać okno w dół i w prawo, ale nigdy w górę i w lewo). Jak sprawić, by działało to dla jedności. Podstawowym pomysłem byłoby

  1. Sprawdź wszystkie okna w bieżącej rzutni
  2. Przejdź na chwilę do żądanej rzutni, aby lewy górny róg przyjął współrzędne 0 0 w tej rzutni
  3. Przenieś wszystkie okna do współrzędnych rzutni zdefiniowanych przez użytkownika
  4. Wróć do starej rzutni (opcjonalnie, może również podążać za oknami)

Rozwiązanie do tworzenia skryptów

Poniższy skrypt wykonuje dokładnie powyższą procedurę. Można go wywołać z dowolną -vflagą, aby ręcznie określić współrzędne, lub można użyć -gflagi, aby wyświetlić okno dialogowe GUI. -fFlaga nakazuje skryptowi również przełączyć rzutnię; jeśli ta flaga nie jest używana - pozostaniesz w bieżącej rzutni i tylko okna będą się poruszać

Uzyskiwanie skryptu

Można skopiować kod źródłowy z tego postu bezpośrednio lub przez github, wykonując następujące czynności:

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

Plik skryptu będzie /opt/sergrep/move_viewport_windows.sh

Aby powiązać skrypt ze skrótem, zobacz temat Jak powiązać pliki .sh z kombinacją klawiatury?

Pamiętaj, że wmctrli xdotoolsą wymagane do poprawnego działania tego skryptu. Możesz je zainstalować za pomocą sudo apt-get install xdotool i wmctrl

Kod źródłowy

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

Próbny

Webm nagrywanie skryptu w akcji:

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

Problemy

Ze względu na gridwtyczkę Unity, która jest odpowiedzialna za przyciąganie okien, skrypt nie może przenosić zmaksymalizowanych lub przyciągniętych w prawo / w lewo okien. Zostanie podjęta próba dodania chwilowego rozbrojenia i resetu tej wtyczki, aby skrypt działał ze wszystkimi oknami, ale ponieważ rozbrojenie i resetowanie ma opóźnienie czasowe, może zostać porzucone jako pomysł. Jeśli chcesz, aby skrypt działał ze wszystkimi oknami, zainstaluj unity-tweak-tooli usuń przyciąganie okien w opcjach Menedżera okien.

Sergiy Kolodyazhnyy
źródło
zdumiewające, jak taka dedykowana odpowiedź dostaje tylko 2-3 pozytywne opinie ...
szaleństwo o natty
3

Środowiska pulpitu inne niż Compiz (XFCE, LXDE, GNOME, KDE ...)

Można użyć kombinacji wmctrli xdotooldo tego. Najpierw upewnij się, że te dwa narzędzia są zainstalowane:

sudo apt-get install xdotool wmctrl

Po spełnieniu zależności, powinieneś być w stanie użyć następującego linijki, aby przenieść wszystkie okna na bieżącym pulpicie na inny:

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)

Szybki podział używanych poleceń:

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

    Wyświetl listę wszystkich okien, odfiltruj te, których nie ma w bieżącym obszarze roboczym, i wyodrębnij ich identyfikator okna

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

    Przenieś okno z identyfikatorem okna $ido obszaru roboczego 2.

  • wszystko to jest zapakowane w prostą while read ... do; donepętlę, która iteruje wszystkie okna na bieżącym pulpicie

Środowiska komputerowe oparte na Compizie (np. Unity)

Znalezienie rozwiązania dla środowisk pulpitu takich jak Unity jest utrudnione przez fakt, że Compiz (menedżer okien Unity) nie używa komputerów stacjonarnych w tradycyjnym znaczeniu .

Glutanimate
źródło
dzięki, wygląda dobrze. ale używam Unity i liczyłem na proste rozwiązanie. Ale jak wspomniałeś, rozwiązanie dla Unity byłoby nieco trudniejsze
betatester07
Tylko mała uwaga, obszar roboczy 2 w „Przenieś okno o identyfikatorze okna $ i do obszaru roboczego 2.” jest właściwie trzecim obszarem roboczym, a nie drugim, ponieważ pierwszy zaczyna się od zera. Więc jeśli masz tylko dwa obszary robocze, skrypt może wyglądać na niedziałający.
Mohamad Fakih