我可以使用键盘一次一个像素地移动或调整窗口大小吗?

我可以使用键盘一次一个像素地移动或调整窗口大小吗?

在 Windows 中(至少从 XP 开始,也可能更早),如果使用键盘移动或调整窗口大小,则可以获得非常精确的位置和大小 - 甚至比使用鼠标更精确 - 通过使用 Ctrl 键与箭头键的组合(在从窗口菜单中调用MoveResize功能 [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 像素,对此我找不到令人满意的解释。好消息是,在不同的计算机上,我没有看到偏差的差异。

如果您遇到窗口意外跳动的情况,请留下评论。


解释

怎么运行的

  1. 最前面的窗口是通过以下方式查找的xprop

    xprop -root
    

    在(广泛的)输出中的某个地方,有一行如下:

    _NET_ACTIVE_WINDOW(WINDOW): window id # 0x4600a8d
    

    从中可以解析出我们的 window-id:0x4600a8d。由于格式与 略有不同wmctrl,我们需要在第三个位置添加一个零:0x04200085

  2. 窗口 ID 用于在 的输出中查找窗口及其当前几何数据wmctrl -lG。一旦我们有了正确的行,我们在窗口上的数据如下所示:

    0x04200085  0 322  52   823  998  <computer_name> <window_name> 
    

    其中第 2、3、4、5 列依次为:

    • 窗口左上角的 x 坐标
    • y 坐标
    • 窗口的宽度
    • 窗口高度
  3. 通过操作这些数字,我们可以使用以下命令移动/调整窗口大小:(
    例如将窗口向右移动 1 像素,将“322”更改为“323”)

    wmctrl -ir 0x04200085 -e 0,323,52,823,998
    

虽然有一些复杂情况需要处理,但基本上这就是它的工作原理。

答案2

显然这在 XFCE 中也行不通。不过我有一个间接的想法,也许可行……

我建议尝试使用辅助功能选项用键盘控制鼠标,将其设置为非常缓慢地移动,并使用它来使窗口一次移动一点点。

每个桌面似乎都将辅助功能选项放在不同的地方,在 XFCE 中它位于常规设置管理器下,但在 Unity 和其他环境中应该不难找到...

相关内容