sds*_*sds 9 command-line window-manager multiple-monitors window-management
这类似于仅使用键盘快速将窗口放置到另一个屏幕,但我希望能够使用命令行(因此我需要做的就是从 bash 历史记录中调用命令行)。
例如,发送
eDP1,VGA1, 和HDMI1 (并在移动后最大化它们 - 但不是疯狂的F11方式,正常的窗口管理器风格的最大化)。
我想通过可执行文件名称指定窗口。
Jac*_*ijm 10
下面的脚本将WM_CLASS通过屏幕名称将属于特定(应用程序)的窗口发送到特定屏幕。脚本中以及下面进一步解释了如何完成。
该脚本假定屏幕是水平排列的,或多或少是顶部对齐的(差异 < 100 PX)。
#!/usr/bin/env python3
import subprocess
import sys
# just a helper function, to reduce the amount of code
get = lambda cmd: subprocess.check_output(cmd).decode("utf-8")
# get the data on all currently connected screens, their x-resolution
screendata = [l.split() for l in get(["xrandr"]).splitlines() if " connected" in l]
screendata = sum([[(w[0], s.split("+")[-2]) for s in w if s.count("+") == 2] for w in screendata], [])
def get_class(classname):
# function to get all windows that belong to a specific window class (application)
w_list = [l.split()[0] for l in get(["wmctrl", "-l"]).splitlines()]
return [w for w in w_list if classname in get(["xprop", "-id", w])]
scr = sys.argv[2]
try:
# determine the left position of the targeted screen (x)
pos = [sc for sc in screendata if sc[0] == scr][0]
except IndexError:
# warning if the screen's name is incorrect (does not exist)
print(scr, "does not exist. Check the screen name")
else:
for w in get_class(sys.argv[1]):
# first move and resize the window, to make sure it fits completely inside the targeted screen
# else the next command will fail...
subprocess.Popen(["wmctrl", "-ir", w, "-e", "0,"+str(int(pos[1])+100)+",100,300,300"])
# maximize the window on its new screen
subprocess.Popen(["xdotool", "windowsize", "-sync", w, "100%", "100%"])
Run Code Online (Sandbox Code Playgroud)
该脚本需要wmctrl和xdotool:
sudo apt-get install xdotool wmctrl
Run Code Online (Sandbox Code Playgroud)将下面的脚本复制到一个空文件中,另存为 move_wclass.py
通过以下命令运行它:
python3 /path/to/move_wclass.py <WM_CLASS> <targeted_screen>
Run Code Online (Sandbox Code Playgroud)
例如:
python3 /path/to/move_wclass.py gnome-terminal VGA-1
Run Code Online (Sandbox Code Playgroud)对于WM_CLASS,你可以使用部分的WM_CLASS在本例中,等等。屏幕名称必须是准确且完整的名称。
解释主要是关于概念,而不是关于编码。
在 xrandr 的输出中,对于每个连接的屏幕,都有一个字符串/行,如下所示:
VGA-1 connected 1280x1024+1680+0
Run Code Online (Sandbox Code Playgroud)
此行让我们在屏幕上的信息位置和它的名字,如解释在这里。
该脚本列出了所有屏幕的信息。当该脚本与屏幕和窗口类为参数运行,它会在屏幕的(x轴)的位置,查找某一类的所有窗口(-id的)(的帮助下wmctrl -l和输出xprop -id <window_id>。
随后,脚本将所有窗口一个接一个地移动到目标屏幕上的某个位置(使用wmctrl -ir <window_id> -e 0,<x>,<y>,<width>,<height>)并将其最大化(使用xdotool windowsize 100% 100%)。
该脚本在我运行它的测试中运行良好。在 Unity 上使用wmctrl,甚至xdotool,可能会有一些顽固的特性,但是有时需要通过实验而不是推理来解决。如果您可能遇到异常,请提及。
小智 5
我已将@jacobs python 代码重写为简单的 bash 并使其正常工作(我在 ubuntu 16 cinnamon 上对此进行了测试)。
我不得不补充说remove,maximized_vert, remove,maximized_horz没有窗户没有移动。
#!/bin/bash
if [ ! -z "$1" ] || [ -z "$2" ]; then
command=$(wmctrl -l | grep $1 | cut -d" " -f1)
if [ ! -z "$command" ]; then
position=$(xrandr | grep "^$2" | cut -d"+" -f2)
if [ ! -z "$position" ]; then
for window in $command; do
wmctrl -ir $window -b remove,maximized_vert
wmctrl -ir $window -b remove,maximized_horz
wmctrl -ir $window -e 0,$position,0,1920,1080
wmctrl -ir $window -b add,maximized_vert
wmctrl -ir $window -b add,maximized_horz
done
else
echo -e "not found monitor with given name"
fi
else
echo -e "not found windows with given name"
fi
else
echo -e "specify window and monitor name;\nmove.sh window-name monitor-name"
fi
Run Code Online (Sandbox Code Playgroud)
sudo apt-get install xdotool wmctrl/path/to/script.sh "window-name" "monitor-name"| 归档时间: |
|
| 查看次数: |
8633 次 |
| 最近记录: |