niv*_*345 5 display window-manager shortcut-keys multiple-monitors unity
我经常使用Ctrl+ Super+ Arrow-Keys 来移动窗口。但是,如果设置了多显示器,快捷方式只会移动当前屏幕上的窗口。
**我的情况示例:
我有 3 个显示器,并且Chrome我的中央显示器中有一个open实例。
我希望看到的是,在 中[2.],窗口移动到最左侧监视器的右半部分,依此类推
我如何实现这种行为?
下面的脚本完全按照您的描述进行操作。它可以在任意数量的屏幕上使用。该脚本针对 Unity 进行了优化,但可以轻松编辑以适应其他窗口管理器。
事实证明,这比我想象的要复杂一些,因为脚本应该考虑到用户可能将启动器设置为仅出现在最左侧的屏幕上(或不出现)。应相应地计算目标位置(和目标窗口大小)。
xdotool和wmctrl- 命令的组合来移动和调整大小。由于这些命令与 Unity 结合可能具有一些“特征行为”,因此细微的更改可能对您的系统有用。然而,我在两个(完全不同的)系统上测试了它,在两个系统上都运行良好。#!/usr/bin/env python3
import subprocess
import sys
# --- set possibly wanted marge (on the right side of the window) below
marge = 0
# --- set set launcher width below (default = 65)
default_launcherwidth = 65
# ---
move = sys.argv[1]
get = lambda cmd: subprocess.check_output(
["/bin/bash", "-c", cmd]).decode("utf-8")
screendata = [l for l in get("xrandr").splitlines() if " connected" in l]
# get the primary screen's position
pr = [l.split() for l in screendata if "primary" in l][0]
i = pr.index("primary"); s = pr[i+1]
primary= [int(s.split("x")[0]), int(s.split("+")[-2])]
# general screen list
screendata = [
[s for s in l.split() if s.count("+") == 2][0] for l in screendata
]
screendata = [
[int(s.split("x")[0]),int(s.split("+")[-2])] for s in screendata
]
screendata.sort(key=lambda x: x[1]); primary = screendata.index(primary)
def launcher_size():
launcherset = get(
"dconf read /org/compiz/profiles/unity/plugins/unityshell/num-launchers"
).strip()
l_size_0 = 65; l_size_1 = l_size_0 if launcherset == "0" else 0
return [l_size_0, l_size_1]
def magnets(index):
l_size = l_sizes[0] if index == primary else l_sizes[1]
screen = screendata[index]
screenwidth = screen[0]; shift = screen[1]
parts = (screenwidth - l_size)/2; virtual_mid = screenwidth - parts + shift
left_trigger = shift + l_size
return [left_trigger, int(virtual_mid), int(parts)]
def find_screen(x_loc):
scr_index = len([scr for scr in screendata if x_loc >= scr[1]])-1
scr_index = scr_index if scr_index >= 0 else 0
screen = screendata[scr_index]
return [scr_index, screen]
def get_active():
active = hex(int(get("xdotool getactivewindow").strip()))
active = active[:2]+(10-len(active))*"0"+active[2:]
x_pos = int([l.split()[2] for l in get("wmctrl -lG").splitlines() \
if l.startswith(active)][0])
return [active, x_pos]
def decide(x_loc, active):
current_scr = find_screen(x_loc)
triggers = magnets(current_scr[0])
width = triggers[2]
index = current_scr[0]
if move == "left":
if x_loc <= triggers[1]:
if x_loc == triggers[0]:
if index != 0:
alter = magnets(index-1)
width = alter[-1]
target = alter[1]
else:
target = triggers[0]
else:
target = triggers[0]
elif x_loc > triggers[1]:
target = triggers[1]
elif move == "right":
if x_loc >= triggers[1]:
if index != len(screendata)-1:
alter = magnets(index+1)
width = alter[-1]
target = alter[0]
else:
target = triggers[1]
elif x_loc < triggers[1]:
target = triggers[1]
subprocess.call([
"wmctrl", "-r", ":ACTIVE:","-b", "remove,maximized_vert,maximized_horz"
])
subprocess.call(["wmctrl", "-ir", active, "-e", "0,"+str(target)+",400,"+\
str(int(width)-marge)+",200"])
subprocess.call([
"wmctrl", "-ir", active, "-b", "toggle,maximized_vert"
])
l_sizes = launcher_size()
w_data = get_active()
active = w_data[0]
x_loc = w_data[1]
decide(x_loc, active)
Run Code Online (Sandbox Code Playgroud)
该脚本需要wmctrl和xdotool:
sudo apt-get instal xdotool wmctrl
Run Code Online (Sandbox Code Playgroud)将脚本复制到一个空文件中,另存为move_window.py
测试 - 通过(重复)命令从终端窗口运行脚本:
python3 /path/to/move_window.py right
Run Code Online (Sandbox Code Playgroud)
这应该将窗口通过屏幕移动到右侧,并且:
python3 /path/to/move_window.py left
Run Code Online (Sandbox Code Playgroud)
这应该将窗口通过屏幕移动到左侧。
如果一切正常,请将这两个命令添加到快捷键:选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。单击“+”并将命令添加到您选择的两个快捷键中。
启动器宽度设置为65px(对应于图标大小48px+17px边框,这是默认值)。如果设置的宽度不同,则应在脚本的头部正确设置,如以下部分所示:
# --- set set launcher width below (default = 65)
default_launcherwidth = 65
# ---
Run Code Online (Sandbox Code Playgroud)在脚本的头部,还有一行:
marge = 0
Run Code Online (Sandbox Code Playgroud)
它在移动屏幕的右侧设置空白边距。如果您愿意,请将其更改为其他值。