Мне удалось получить Аэро поспешную левую и правую работу в метагороде Ubuntu 14.10, и теперь я хотел бы придумать корректное winctrl
команды так, чтобы я мог подражать тому же эффекту на две экранных установки, куда два экрана помещаются горизонтально друг рядом с другом как в изображении ниже. Я хочу, чтобы это работало над Метагородом (классик GNOME), я не готов переместиться в другие менеджеры окон вообще, так как я знаю, что у некоторых из них уже есть эти возможности, встроенные. Таким образом, это - вопрос попытаться найти ответ для Метагорода средой классика GNOME конкретно:
То, что я хочу, должно расширить мой ток winctrl
команды. Они в настоящее время работают при помощи половины общей ширины экрана любой левый или правый из общей экранной длины. Ввод 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)
Я протестировал сценарий ниже на Ubuntu (Gnome) Классик и Ретроспективный кадр Gnome (Метагород) 14.04. "Смешанное" приложение xdotool
и wmctrl
было необходимо из-за некоторых особенностей, я столкнулся с записью сценария для Метагорода.
В результате того, что я хотел сценарий к:
- сценарий стал немного более обширным затем, я предвидел.
Если второй монитор подключен:
Это работает в значительной степени, как Вы описываете:
Если никакой второй монитор не подключен:
Это работает традиционным способом:
Установите обоих 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 (последняя версия)