Ubuntu 14.10 Aero snap в двух горизонтальной установке экрана?
Мне удалось настроить Aero snap влево и вправо, работая в metacity Ubuntu 14.10, и теперь я хотел бы найти правильный winctrl
команды, чтобы я мог имитировать тот же эффект на двух экранах, где два экрана расположены горизонтально рядом друг с другом, как на рисунке ниже. Я хочу, чтобы это работало в Metacity (классика GNOME), я вообще не хочу переходить на другие оконные менеджеры, поскольку знаю, что некоторые из них уже имеют эти встроенные возможности. Так что это вопрос, чтобы попытаться найти ответ для классической среды Metacity GNOME:
То, что я хочу, это расширить мой текущий winctrl
команды. В настоящее время они работают, используя половину общей ширины экрана слева или справа от общей длины экрана. Typing Super_L+left
заставит активное окно использовать левую половину, и набрав Super_L+right
заставит активное окно использовать правую половину размера всех горизонтальных пикселей.
[hpenvy15 ~] $ cat > ~/bin/left.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,0,0,`xwininfo -root | grep Width | awk '{ print (($2/2))}'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C
[hpenvy15 ~] $ cat > ~/bin/right.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,`xwininfo -root | grep Width | awk '{ print (($2/2)+5) ",0," (($2/2)) }'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C
В новой установке с двумя экранами у меня ширина 1920+1920 пикселей. Идеальная ширина окна - половина 1920 года, это 1920/2=960. Хотелось бы по новой left
а также right
Команды для расчета, где находится окно, в настоящее время, если left
набирается, чтобы перейти к ближайшему блоку пикселей шириной 960, в любом из 4 блоков, присутствующих в конфигурации с двумя экранами, 1920+1920, но также работает с ближайшим блоком шириной 960 в конфигурации одного экрана 1920. Диаграмма показана ниже:
Это конфигурация, когда у меня внешний экран в 1 и 2, а экран ноутбука в 3 и 4. В настоящее время, нажав Super_L+left
переместит окно в левую половину экрана TotalWidth/2, которая будет слишком большой, и перейдет к 1+2.
Я бы хотел первый left
команда, чтобы переместить его на панель 3, затем следующий left
команда, чтобы переместить его в 2, затем следующий, чтобы переместить его в 1.
+-------------------++-------------------++-------------------++-------------------+
| || || || +------------+ |
| || || || | | |
| || || <-------++-+ | |
| || || || | | |
| 1 || 2 || 3 || | 4 | |
| || || || | | |
| || || || +------------+ |
| || || || |
| || || || |
+-------------------++-------------------++-------------------++-------------------+
Это конфигурация, когда у меня только экран ноутбука в две половины шириной 960 пикселей.
В настоящее время, нажав Super_L+right
переместит окно в правую половину экрана TotalWidth/2, что соответствует числу 4.
+-------------------++-------------------+
| +------------+ || |
| | | || |
| | | || |
| | |----++---> |
| | 3 | || 4 |
| | | || |
| | | || |
| +------------+ || |
| || |
+-------------------++-------------------+
Это вывод wmctrl
когда два экрана включены:
wmctrl -d
0 * DG: 3840x1080 VP: 0,0 WA: 0,0 3840x1080 Workspace 1
1 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 2
2 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 3
3 - DG: 3840x1080 VP: N/A WA: 0,0 3840x1080 Workspace 4
И это вывод xrandr
также когда два экрана включены:
[hpenvy15 ~] $ xrandr
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 193mm
1920x1080 60.1*+ 59.9 40.0
1680x1050 60.0 59.9
1600x1024 60.2
1400x1050 60.0
1280x1024 60.0
1440x900 59.9
1280x960 60.0
1360x768 59.8 60.0
1152x864 60.0
1024x768 60.0
800x600 60.3 56.2
640x480 59.9
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 521mm x 293mm
1920x1080 60.0*+ 50.0 59.9 30.0 25.0 24.0 30.0 24.0
1920x1080i 60.1 50.0 60.0
1680x1050 59.9
1600x900 60.0
1280x1024 75.0 60.0
1440x900 59.9
1366x768 59.8
1280x800 59.9
1152x864 75.0
1280x720 60.0 50.0 59.9
1440x576i 50.1
1024x768 75.1 70.1 60.0
1440x480i 60.1 60.1
832x624 74.6
800x600 72.2 75.0 60.3
720x576 50.0
720x480 60.0 59.9
640x480 75.0 72.8 66.7 60.0 59.9
720x400 70.1
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
1 ответ
Я тестировал приведенный ниже скрипт на Ubuntu (Gnome) Classic и Gnome Flashback (Metacity) 14.04. "Смешанное" применение xdotool
а также wmctrl
было необходимо из-за некоторых особенностей, с которыми я столкнулся при написании сценария для Metacity.
Решение
В результате того, что я хотел, чтобы скрипт:
- определить, какой левый / правый экран
- рассчитать разрешение обоих мониторов
- также отлично работает, если два экрана имеют разное разрешение (и рассчитывают как положения, так и целевые размеры окон)
- работает нормально, если подключен второй экран или нет
- сценарий стал немного более обширным, чем я предвидел.
Что оно делает:
Если подключен второй монитор:
Это работает в значительной степени, как вы описываете:
- он разделяет два экрана на четыре области, каждая из которых имеет половину размера экрана, на котором она расположена (как сказано, также с разными разрешениями)
- запустив его с опцией "влево" или "вправо":
- он перемещает окно в область слева / справа от окна
- изменяет размеры по горизонтали до половины размера целевого экрана
- максимизирует окно по вертикали
Если второй монитор не подключен:
Работает традиционным способом:
- запустить с параметром "влево", это максимизирует самое переднее окно по вертикали в левой половине экрана
- запустить с опцией "вправо", это максимизирует самое переднее окно по вертикали на правой половине экрана
Как это использовать
Установите оба
xdotool
а такжеwmctrl
:sudo apt-get install wmctrl sudo apt-get install xdotool
Скопируйте скрипт в пустой файл, сохраните его как
aero.py
запустить его по командеpython3 /path/to/aero.py left python3 /path/to/aero.py right
Сценарий
#!/usr/bin/env python3
import subprocess
import sys
move = sys.argv[1]
def get(cmd):
return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def execute(cmd):
subprocess.call(["/bin/bash", "-c", cmd])
# screen resolutions ("raw")
wds = [s for s in get("xrandr").split() if s.endswith("+0")]
# x-res left/right)
left = [scr.split("x")[0] for scr in wds if scr.endswith("+0+0")]
right = [scr.split("x")[0] for scr in wds if not scr.endswith("+0+0")]
# x-positions areas
left_pos = [0, int(int(left[0])/2), int(left[0])]
right_pos = [int(int(left[0])+int(right[0])/2)] if len(right) != 0 else []
x_positions = left_pos+right_pos
# frontmost window pos
frontmost =get("printf 0x%x "+get("xdotool getwindowfocus").strip())
frontmost = frontmost[:2]+"0"+frontmost[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if frontmost in l][0][:6]
curr_pos = int(f_data[2])
area = len([x for x in x_positions if x <= curr_pos])
if move == "left":
i = area-2; target_pos = x_positions[i] if i >= 0 else 0
elif move == "right":
i = area; target_pos = x_positions[area] if area < len(x_positions) else x_positions[-1]
if i >= 2:
perc = int((100*(x_positions[-1]-x_positions[-2])/sum([int(it) for it in left+right])))
else:
perc = int((100*(x_positions[1]-x_positions[0])/sum([int(it) for it in left+right])))
# execute actions
cmd1 = "wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz"
cmd2 = "wmctrl -ir "+f_data[0]+" -e 0,"+str(target_pos)+","+"30,300,300"
cmd3 = "xdotool windowsize $(xdotool getactivewindow) "+str(perc)+"% 100%"
for cmd in [cmd1, cmd2, cmd3]:
execute(cmd)
Также опубликовано на gist.gisthub (последняя версия)