Thống nhất: Viewports là gì?
Ubuntu Unity sử dụng chế độ xem - về cơ bản là một hệ tọa độ (với tọa độ 0,0 là góc trên cùng bên trái), trong đó một máy tính để bàn khổng lồ được chia thành các khối phù hợp với độ phân giải màn hình của bạn. Tọa độ tăng giá trị khi bạn di chuyển sang phải và xuống dưới.
Hệ tọa độ là tương đối. Nếu chế độ xem hiện tại của tôi ở trên cùng bên trái, mọi thứ liên quan đến chế độ xem đó sẽ là các giá trị dương theo gia số chiều rộng và chiều cao. Chẳng hạn, nếu chế độ xem hiện tại của tôi ở trên cùng bên trái, cửa sổ firefox trong không gian làm việc ở giữa trên cùng mà bạn thấy ở trên được đặt ở giá trị x 1366 và giá trị y 0 so với chế độ xem ngoài cùng bên trái. Nếu chế độ xem hoạt động của tôi ở giữa trên cùng, cửa sổ đầu cuối ở chế độ xem ngoài cùng bên trái được đặt ở giá trị x -1327 60. Đây là vấn đề chínhxdotool
vì xdotool
không xử lý các số âm.
Cũng lưu ý rằng, góc trên cùng bên trái của chế độ xem hiện tại của bạn sẽ luôn được xdotool giả sử là tọa độ 0 0. Điều đó có nghĩa là chúng ta chỉ có thể di chuyển công cụ đúng và xuống.
Làm xdotool hoạt động cho Unity
Bây giờ chúng tôi biết rằng xdotool
có thể di chuyển các cửa sổ chỉ liên quan đến góc trên bên trái của chúng tôi (nghĩa là bạn luôn có thể di chuyển cửa sổ xuống và phải, nhưng không bao giờ lên và sang trái). Làm thế nào để chúng ta làm việc đó cho sự thống nhất. Chà, ý tưởng cơ bản sẽ là
- Chỉ ra tất cả các cửa sổ trên chế độ xem hiện tại
- Di chuyển đến chế độ xem được yêu cầu trong giây lát để tạo góc trên cùng bên trái giả sử tọa độ 0 0 tại chế độ xem đó
- Di chuyển tất cả các cửa sổ sang tọa độ khung nhìn do người dùng xác định
- Quay trở lại chế độ xem cũ (tùy chọn, cũng có thể theo các cửa sổ)
Giải pháp kịch bản
Kịch bản dưới đây thực hiện chính xác các thủ tục được mô tả ở trên. Nó có thể được gọi bằng một trong hai -v
cờ để chỉ định tọa độ theo cách thủ công hoặc bạn có thể sử dụng -g
cờ để hiển thị hộp thoại GUI. -f
cờ sẽ báo cho kịch bản chuyển đổi chế độ xem; nếu cờ đó không được sử dụng - bạn sẽ vẫn ở chế độ xem hiện tại và chỉ các cửa sổ sẽ được di chuyển xung quanh
Lấy kịch bản
Người ta có thể sao chép mã nguồn từ bài đăng này trực tiếp hoặc thông qua github bằng các bước sau:
sudo apt-get install git
cd /opt ; sudo git clone https://github.com/SergKolo/sergrep.git
sudo chmod -R +x sergrep
Tệp script sẽ là /opt/sergrep/move_viewport_windows.sh
Để liên kết tập lệnh với phím tắt, hãy tham khảo Làm cách nào để liên kết các tệp .sh với tổ hợp bàn phím?
Lưu ý rằng wmctrl
và xdotool
được yêu cầu để kịch bản này hoạt động đúng. Bạn có thể cài đặt chúng qua sudo apt-get install xdotool và wmctrl
Mã nguồn
#!/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 "$@"
Bản giới thiệu
Webm ghi lại kịch bản đang hoạt động:
https://www.youtube.com/watch?v=cJMlC41CWWo
Các vấn đề
Do grid
plugin của Unity chịu trách nhiệm chụp nhanh cửa sổ, tập lệnh không thể di chuyển các cửa sổ được bật tối đa hoặc phải / trái. Nó sẽ được cố gắng thêm phần không cài đặt tạm thời và đặt lại plugin đó để làm cho tập lệnh hoạt động với tất cả các cửa sổ, nhưng vì việc đặt lại và đặt lại có độ trễ về thời gian, nó có thể bị bỏ qua như một ý tưởng. Nếu bạn muốn tập lệnh hoạt động với tất cả các cửa sổ, hãy cài đặt unity-tweak-tool
và bỏ cài đặt cửa sổ chụp bên dưới các tùy chọn Trình quản lý cửa sổ.