Собственно, на tiled wm перелезать как-то неохота, но автоматический
ресайз терминалов иметь хочется. ArrangeWindows во флаксе как-то совсем не порадовал - оно не осиливает даже неперекрывающиеся окна
сделать. Поэтому родил скриптик, который делает это автоматом.
Как юзать: сохранить куда-нибудь, забиндить вот такое в своеём
WM'e:
xterm -e «/path/to/tile.sh -ls»;path/to/tile.sh
на любимое сочетание клавиш.
С аргументом -ls оно запустит в терминале шелл, а по выходу
ещё раз образмерит оставшиеся окна.
Собственно вот:
#!/bin/bash
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# Version 2, December 2004
#
# Copyright (C) 2004 Sam Hocevar
# 14 rue de Plaisance, 75014 Paris, France
# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.
#
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
#
# 0. You just DO WHAT THE FUCK YOU WANT TO.
# Tiled-WM-like-terminal launcher
#
# How to use?
#
# Bind the following command to you favourite key combination
# in your favourite WM. It will execute your favourite terminal
# and when it will connect to X server, it will call this script
# to resize all windows on current desktop in Tiled-WM-like manner
# and run shell specified in SHELLCMD
#
# xterm -e <path to>/tile.sh -ls;<path to>/tile.sh
#
# the -ls will run shell after tiling, and being
# run with arguments, it will just tile windows,
# so when terminal closes, no empty space will be left
#
# Note:
# Currently resize is a bit widescreen-centric and expects dx > dy
SHELLCMD="/bin/bash -l"
calculate_positions()
{
awk -vcount="$1" -vx="$2" -vy="$3" '
# Fill rectangle with xcount rows horizontally and ycount columns vertically
function fill_rect(xcount,ycount,left,top,dx,dy)
{
use ABS_TOP;
use ABS_LEFT;
use WIN_ADDON_X;
use WIN_ADDON_Y;
# width/height of single window
width = int(dx / xcount);
height = int(dy / ycount);
wtop = 0;
wleft = 0;
for (i = 0; i < xcount; i++)
{
wleft = left + i * width;
for (j = 0; j < ycount; j++)
{
wtop = top + j * height;
printf("%d,%d,%d,%d ",wleft,wtop,width - WIN_ADDON_X,height-WIN_ADDON_Y);
}
}
}
function get_div(count,dx,dy)
{
use ABS_TOP;
use ABS_LEFT;
use WIN_ADDON_X;
use WIN_ADDON_Y;
root = int(sqrt(count));
left = count - root*root;
# exact root: fill whole screen with equal number of windows
if (left == 0)
{
fill_rect(root,root,ABS_LEFT,ABS_TOP,dx - ABS_LEFT,dy - ABS_TOP);
return;
}
else
{
# fill square in center,
# left windows tile vertically in right rectangular
# Assume dx > dy
fill_rect(root,root,ABS_LEFT,ABS_TOP,dy - ABS_LEFT ,dy - ABS_TOP);
fill_rect(1,left,dy + WIN_ADDON_X,ABS_TOP,dx - dy - WIN_ADDON_X, dy - ABS_TOP);
}
}
BEGIN {
# Some space in pixel to skip on top
ABS_TOP = 30;
# Some space in pixel to skip on left
ABS_LEFT = 10;
# Give some amount of pixels for each window - for border/space between
WIN_ADDON_X = 5;
# Give some amount of pixels for WM decorations
WIN_ADDON_Y = 30;
get_div(count,x,y);
printf("\n");
}
'
}
tile()
{
# Find current desktop
ACTIVE_DESKTOP=$(wmctrl -d|awk '{ if ($2 == "*")print $1; }')
# Colled IDs of all windows
DESKTOP_WINS=$(wmctrl -l | awk "{ if (\$2 == $ACTIVE_DESKTOP) print \$1 }" | xargs)
# Count windows number
WINS_COUNT=$(echo $DESKTOP_WINS|wc -w)
# Get size of visible/working area for current desktop
DESKTOP_X=$(wmctrl -d | awk "{ if ((NR-1) == $ACTIVE_DESKTOP) { split(\$9,arr,\"x\"); print arr[1];} }")
DESKTOP_Y=$(wmctrl -d | awk "{ if ((NR-1) == $ACTIVE_DESKTOP) { split(\$9,arr,\"x\"); print arr[2];} }")
# Calculate geometry (in pixels for each window)
# and save into array
POSITIONS=($(calculate_positions $WINS_COUNT $DESKTOP_X $DESKTOP_Y))
# Walk thorough all windows and move/resize it to fill the desktop
I=0
for WINID in $DESKTOP_WINS
do
wmctrl -i -r "$WINID" -e "0,${POSITIONS[$I]}"
I=$((I + 1))
done
}
# Did you install wmctrl?
# http://tomas.styblo.name/wmctrl/
WMCTRL=$(type -P wmctrl)
if [ $? != 0 ]
then
echo "Ooops: wmctrl is not found"
exit 1
fi
tile
# run shell if requsted
[ $# -gt 0 ] && [ "$1" = "-ls" ] && $SHELLCMD
Пробуем, отписываемся о результатах/где пробовали: WM/DE.
Нужно чтобы была установлена утилитка wmctrl и оконный менеджер
понимал стандарты. Тестировано на fluxbox'e.
Из минусов - дополнительно висящий шелл на каждое окно, алгоритм
ресайза стоит наверное слегка пересмотреть. На 16:9 работает неплохо,
на 4:3 несколько печальнее.