So verschieben Sie alle Fenster in einen anderen Arbeitsbereich

8

Ist es möglich, alle Fenster (oder alle nicht minimierten Fenster) von einem Arbeitsbereich in einen anderen zu verschieben?

Ich weiß, dass ich mit Shift+ Ctrl+ Alt+ ein Fenster in einen anderen Arbeitsbereich verschieben kann arrow, aber es wird nur dieses eine fokussierte Fenster verschoben.

betatester07
quelle
Interessieren Sie sich noch für eine Unity-Lösung?
Jacob Vlijm
Ja, ich wollte eine Lösung für Unity. Entschuldigung, ich habe nicht genau angegeben, dass ich Unity verwende
betatester07
Hast du das bemerkt? Ich habe es nicht versucht, weiß nicht, ob es noch funktioniert. Wenn nicht, könnte ich nach einer Alternative unter einer Tastenkombination suchen.
Jacob Vlijm
Ah, sorry, das ist für ein einziges Fenster, werde hineinschauen!
Jacob Vlijm
Habe daran gearbeitet und habe eine "Art" Arbeitsskript. Zufällig auftretende Probleme machen es jedoch kaum nutzbar. werde es posten, wenn ich herausfinde, was es verursacht.
Jacob Vlijm

Antworten:

5

Einheit: Was sind Ansichtsfenster?

Ubuntu Unity verwendet Ansichtsfenster - im Grunde genommen ein Koordinatensystem (wobei die Koordinate 0,0 in der oberen linken Ecke steht), bei dem ein riesiger Desktop in Abschnitte unterteilt ist, die Ihrer Bildschirmauflösung entsprechen. Koordinaten gewinnen an Wert, wenn Sie sich nach rechts und unten bewegen.

Geben Sie hier die Bildbeschreibung ein

Das Koordinatensystem ist relativ. Wenn sich mein aktuelles Ansichtsfenster oben links befindet, sind alle Werte in Bezug auf dieses Ansichtsfenster positive Werte in Schritten von Breite und Höhe. Wenn sich mein aktuelles Ansichtsfenster beispielsweise ganz links oben befindet, befindet sich das Firefox-Fenster im oberen mittleren Arbeitsbereich, das Sie oben sehen, auf dem x-Wert 1366 und dem y-Wert 0 relativ zum Ansichtsfenster ganz links oben. Wenn mein aktives Ansichtsfenster oben in der Mitte angezeigt wird, befindet sich das Terminalfenster oben links im Ansichtsfenster auf dem x-Wert -1327 60. Dies ist dasxdotool Hauptproblem für , da xdotooles sich nicht um negative Zahlen handelt.

Beachten Sie auch, dass die obere linke Ecke Ihres aktuellen Ansichtsfensters von xdotool immer als Koordinaten 0 0 angenommen wird. Das heißt, wir können nur Sachen nach rechts und unten bewegen.

Damit xdotool für Unity funktioniert

Jetzt wissen wir, dass xdotoolFenster nur relativ zu unserer oberen linken Ecke verschoben werden können (dh Sie können Fenster immer nach unten und rechts verschieben, aber niemals nach oben und links). Wie schaffen wir das für die Einheit? Nun, die Grundidee wäre zu

  1. Finden Sie alle Fenster im aktuellen Ansichtsfenster heraus
  2. Wechseln Sie kurz zu einem angeforderten Ansichtsfenster, damit die obere linke Ecke die Koordinaten 0 0 in diesem Ansichtsfenster annimmt
  3. Verschieben Sie alle Fenster in benutzerdefinierte Ansichtsfensterkoordinaten
  4. Kehren Sie zum alten Ansichtsfenster zurück (optional, könnte auch den Fenstern folgen)

Skriptlösung

Das folgende Skript führt genau das oben beschriebene Verfahren aus. Es kann entweder mit dem -vFlag aufgerufen werden, um die Koordinaten manuell anzugeben, oder Sie können das -gFlag verwenden, um den GUI-Dialog aufzurufen. -fDas Flag weist das Skript an, auch das Ansichtsfenster zu wechseln. Wenn dieses Flag nicht verwendet wird, bleiben Sie im aktuellen Ansichtsfenster und nur Fenster werden verschoben

Das Skript erhalten

Sie können den Quellcode aus diesem Beitrag direkt oder über Github mit den folgenden Schritten kopieren:

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

Die Skriptdatei wird /opt/sergrep/move_viewport_windows.sh

Informationen zum Binden von Skripten an Verknüpfungen finden Sie unter Wie binde ich .sh-Dateien an eine Tastaturkombination?

Beachten Sie, dass wmctrlund xdotoolerforderlich sind, damit dieses Skript ordnungsgemäß funktioniert. Sie können sie über sudo apt-get install xdotool und wmctrl installieren

Quellcode

#!/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

Webm-Aufzeichnung des Skripts in Aktion:

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

Probleme

Aufgrund des Unity- gridPlugins, das für das Einrasten von Fenstern verantwortlich ist, kann das Skript die maximierten oder rechts / links eingerasteten Fenster nicht verschieben. Es wird versucht, das momentane Deaktivieren und Zurücksetzen dieses Plugins hinzuzufügen, damit das Skript mit allen Fenstern funktioniert. Da das Deaktivieren und Zurücksetzen jedoch zeitverzögert ist, wird es möglicherweise als Idee abgebrochen. Wenn Sie möchten, dass das Skript mit allen Fenstern funktioniert, installieren unity-tweak-toolund deaktivieren Sie das Einrasten von Fenstern unter den Optionen des Fenstermanagers.

Sergiy Kolodyazhnyy
quelle
Erstaunlich, wie eine engagierte Antwort wie diese nur 2-3 positive Stimmen bekommt ...
verrückt nach Natty
3

Nicht auf Compiz basierende Desktop-Umgebungen (XFCE, LXDE, GNOME, KDE ...)

Sie können dafür eine Kombination aus wmctrlund verwenden xdotool. Stellen Sie zunächst sicher, dass diese beiden Dienstprogramme installiert sind:

sudo apt-get install xdotool wmctrl

Wenn die Abhängigkeiten erfüllt sind, sollten Sie in der Lage sein, mit dem folgenden Einzeiler alle Fenster auf dem aktuellen Desktop auf einen anderen zu verschieben:

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)

Eine kurze Aufschlüsselung der verwendeten Befehle:

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

    Listen Sie alle Fenster auf, filtern Sie diejenigen heraus, die sich nicht im aktuellen Arbeitsbereich befinden, und extrahieren Sie ihre Fenster-ID

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

    Verschieben Sie das Fenster mit der Fenster-ID $iin den Arbeitsbereich 2.

  • All dies ist in einer einfachen while read ... do; doneSchleife gepackt , die über alle Fenster auf dem aktuellen Desktop iteriert

Compiz-basierte Desktop-Umgebungen (z. B. Unity)

Die Suche nach einer Lösung für Desktop-Umgebungen wie Unity wird dadurch erschwert, dass Compiz (Unitys Fenstermanager) keine Desktops im herkömmlichen Sinne verwendet .

Glutanimat
quelle
Danke, es sieht gut aus. Aber ich benutze Unity und hoffte auf eine einfache Lösung. Aber wie Sie bereits erwähnt haben, wäre die Lösung für Unity etwas schwieriger
betatester07
Nur eine kleine Bemerkung, Arbeitsbereich 2 in "Fenster mit Fenster-ID $ i in Arbeitsbereich 2 verschieben". ist eigentlich der dritte Arbeitsbereich, nicht der zweite, da der erste mit Null beginnt. Wenn Sie also nur zwei Arbeitsbereiche haben, funktioniert das Skript möglicherweise nicht.
Mohamad Fakih