LINUX.ORG.RU
ФорумTalks

[наваял скрипт] Tiled WM для бедных <пользователей гнома? ;-)>


0

1

Собственно, на 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 несколько печальнее.

★★

Чем

gconftool-2 -s /desktop/gnome/session/required_components/windowmanager xmonad --type string

не устроил? Возможно после замены xmonad на awesome/dwm/ion3/etc.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

ну целиком на tiled wm переезжать не хочется, когда путём небольших изменений твой любимый делает всё что тебе надо.

deadman ★★
() автор топика
Ответ на: комментарий от kernelpanic

pytile посмотрел; но он кстати неправильно считает размеры десктопа - во флуксе вылезает за слит, также работает для всех запускаемых окон.

deadman ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.