在 Windows 中(至少从 XP 开始,也可能更早),如果使用键盘移动或调整窗口大小,则可以获得非常精确的位置和大小 - 甚至比使用鼠标更精确 - 通过使用 Ctrl 键与箭头键的组合(在从窗口菜单中调用Move
或Resize
功能 [Alt+Space] 之后)将窗口边框一次移动一个像素。
有没有办法在 Ubuntu 中做同样(或类似)的事情?
答案1
将窗口移动/调整大小 1px
假设您使用的是 Unity,下面的脚本会将窗口移动或调整大小 1 像素。该脚本可以使用 8 个不同的参数运行。根据您要使用的移动/调整大小选项,您可以将命令添加到快捷键组合中。以下是选项和相应命令的概述:
例外/限制
有一些限制:
gnome-terminal
窗口只能逐步调整大小。因此,将窗口大小增加/减少 1px 不起作用gnome-terminal
。- 要移动或调整大小的窗口需要至少距离 Unity 启动器和顶部面板都有几个像素。
如何使用
首先安装 wmctrl,它是获取窗口几何形状和移动窗口所必需的。
sudo apt-get install wmctrl
创建一个目录
~/bin
(位于你的主目录中)- 将以下脚本复制到一个空文件中,另存为
move_window
(无扩展名) 使其可执行(右键单击文件>属性>权限(选项卡),勾选“允许执行”)
为了测试,打开一个终端窗口并随后运行:
move_window l move_window r move_window u move_window d
由于终端窗口位于最前面,它应该向左/向右/向上/向下移动 1px。
(如上所述,调整大小不适用于
gnome-terminal
)如果一切正常,请将命令添加到快捷键中;
选择:系统设置 > “键盘” > “快捷键” > “自定义快捷键”。单击“+”并将命令添加到四个不同的快捷键组合中。这可能有点棘手,因为您提到的命令可能已被占用。在我的系统上有效的方法:- Shift+ Ctrl+arrow key left
- Shift+ Ctrl+arrow key right
- Shift+ Ctrl+arrow key up
- Shift+ Ctrl+arrow key down
对于移动操作。
对于调整大小操作,您必须尝试其他组合。
剧本
#!/usr/bin/env python3
import subprocess
import sys
# calibration
cal = 4
# direction, as argument from user input (l, r, u, d / h+, h-, v+, v-)
direction = sys.argv[1]
# move step size
mv = -1 if direction in ["l", "d", "h-", "v-"] else 1
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command])\
.decode("utf-8")
def execute(command):
subprocess.call(["/bin/bash", "-c", command])
# find the top shift (height of the panel = resolution - working area)
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))[-1]
topshift = int(res) - int(get("wmctrl -d").split()[8].split("x")[-1])+cal
# find frontmost window
def get_windowid():
cmd = "xprop -root"
frontmost = [l for l in get(cmd).splitlines() if\
"ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
return frontmost[:2]+"0"+frontmost[2:]
# get window geometry, create move command
set_w = [w.split()[0:6] for w in get("wmctrl -lG").splitlines()\
if get_windowid() in w][0]
set_w[0] = "wmctrl -ir "+set_w[0]+" -e 0"
set_w.pop(1)
if direction in ["l", "r"]:
set_w[1] = str(int(set_w[1])+mv); set_w[2] = str(int(set_w[2])-topshift)
elif direction in ["u", "d"]:
set_w[2] = str(int(set_w[2])-topshift-mv)
elif direction in ["v-", "v+"]:
set_w[2] = str(int(set_w[2])-topshift); set_w[4] = str(int(set_w[4])+mv)
elif direction in ["h-", "h+"]:
set_w[2] = str(int(set_w[2])-topshift); set_w[3] = str(int(set_w[3])+mv)
execute((",").join(set_w))
笔记
方式上有些不同wmctrl
报告窗口的几何形状,以及方式wmctrl
套窗口几何形状。第一种情况下,它从全屏(分辨率)计算,第二种情况下,它仅从工作区域(??)计算。即便如此,脚本也必须垂直“校准” 4 像素,对此我找不到令人满意的解释。好消息是,在不同的计算机上,我没有看到偏差的差异。
如果您遇到窗口意外跳动的情况,请留下评论。
解释
怎么运行的
最前面的窗口是通过以下方式查找的
xprop
:xprop -root
在(广泛的)输出中的某个地方,有一行如下:
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x4600a8d
从中可以解析出我们的 window-id:
0x4600a8d
。由于格式与 略有不同wmctrl
,我们需要在第三个位置添加一个零:0x04200085
窗口 ID 用于在 的输出中查找窗口及其当前几何数据
wmctrl -lG
。一旦我们有了正确的行,我们在窗口上的数据如下所示:0x04200085 0 322 52 823 998 <computer_name> <window_name>
其中第 2、3、4、5 列依次为:
- 窗口左上角的 x 坐标
- y 坐标
- 窗口的宽度
- 窗口高度
通过操作这些数字,我们可以使用以下命令移动/调整窗口大小:(
例如将窗口向右移动 1 像素,将“322”更改为“323”)wmctrl -ir 0x04200085 -e 0,323,52,823,998
虽然有一些复杂情况需要处理,但基本上这就是它的工作原理。
答案2
显然这在 XFCE 中也行不通。不过我有一个间接的想法,也许可行……
我建议尝试使用辅助功能选项用键盘控制鼠标,将其设置为非常缓慢地移动,并使用它来使窗口一次移动一点点。
每个桌面似乎都将辅助功能选项放在不同的地方,在 XFCE 中它位于常规设置管理器下,但在 Unity 和其他环境中应该不难找到...