我设法得到Aero 左右快照在 metacity Ubuntu 14.10 中工作现在我想找到正确的winctrl
命令,以便能够在双屏设置上模拟相同的效果,其中两个屏幕水平放置在一起,如下图所示。我希望这可以在 Metacity(GNOME 经典版)上运行,我根本不愿意转到其他窗口管理器,因为我知道其中一些已经内置了这些功能。所以这是一个尝试找到 Metacity 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
输入了,则转到两个屏幕、1920+1920 配置中存在的 4 个块中的任何一个中最近的 960 宽像素块,但也可以在单屏 1920 配置中工作到最近的 960 宽块。下图所示:
这是我在 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 上测试了下面的脚本。由于我在为 Metacity 编写脚本时遇到了一些特殊情况,因此必须“混合”使用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(最新版本)