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.
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 xdotool
es 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 xdotool
Fenster 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
- Finden Sie alle Fenster im aktuellen Ansichtsfenster heraus
- Wechseln Sie kurz zu einem angeforderten Ansichtsfenster, damit die obere linke Ecke die Koordinaten 0 0 in diesem Ansichtsfenster annimmt
- Verschieben Sie alle Fenster in benutzerdefinierte Ansichtsfensterkoordinaten
- 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 -v
Flag aufgerufen werden, um die Koordinaten manuell anzugeben, oder Sie können das -g
Flag verwenden, um den GUI-Dialog aufzurufen. -f
Das 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:
sudo apt-get install git
cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
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 wmctrl
und xdotool
erforderlich 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: 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 "$@"
Demo
Webm-Aufzeichnung des Skripts in Aktion:
https://www.youtube.com/watch?v=cJMlC41CWWo
Probleme
Aufgrund des Unity- grid
Plugins, 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-tool
und deaktivieren Sie das Einrasten von Fenstern unter den Optionen des Fenstermanagers.