我使用了多个 Chrome 窗口(3-5 个),每个窗口都打开了许多选项卡,并且我使用了“启动时”>“从上次中断的地方继续”设置。问题是,当我启动 Chrome 时,所有窗口都在当前工作区中打开(我使用了 4 个工作区)。我需要做的是将每个窗口移动到特定的工作区。我需要通过窗口的 ID 来选择窗口,因为窗口的标题可能总是不同的(取决于哪个选项卡处于焦点状态)。一直手动将窗口移动到正确的工作区有点烦人。
这是我的命令的输出wmctrl -l
:
wmctrl -l
0x01e00002 0 posuk13-PCSPEC XdndCollectionWindowImp
0x01e00005 0 posuk13-PCSPEC unity-launcher
0x01e00008 0 posuk13-PCSPEC unity-panel
0x01e0000b 0 posuk13-PCSPEC unity-dash
0x01e0000c 0 posuk13-PCSPEC Hud
0x0300000a 0 posuk13-PCSPEC Desktop
0x04400001 0 posuk13-PCSPEC Inbox - [email protected] - Gmail - Google Chrome
0x04400039 0 posuk13-PCSPEC How to move Chrome windows using wmctrl? - Ask Ubuntu - Google Chrome
0x0440003a 0 posuk13-PCSPEC YouTube - Google Chrome
0x0440003b 0 posuk13-PCSPEC Online regex tester and debugger: JavaScript, Python, PHP, and PCRE - Google Chrome
现在假设我需要将 YouTube 窗口移动到工作区 #2。以下命令有效:
wmctrl -r YouTube -e 0,2000,0,-1,-1
并且这也有效:
wmctrl -r 0x0440003a -i -e 0,2000,0,-1,-1
但问题是每次重启时窗口 ID 都不同,每次切换选项卡时其标题也不同。有没有办法通过 ID 的一部分(最后 3-4 位数字)来选择窗口(当我在重启后立即启动窗口时,最后 2-3 位数字似乎总是相同的),或者从列表中选择例如第 7 个窗口?我需要这样做的原因是我想编写脚本来启动所有必需的应用程序(Chrome、Apache、SublimeText……)并将窗口移动到特定的工作区(我有一个用于电子邮件/Facebook 的工作区,一个用于音乐,一个用于工作)。
PS:请不要建议使用系统休眠功能 - 这对我来说不是一个选择,因为有些驱动程序问题。
PS2: 我使用的是 Ubuntu 15.04
答案1
如何识别 Chrome 的特定窗口
如果窗口总是按相同的时间顺序创建(在启动时)(正如您在评论中提到的那样),您可以使用命令输出的特定属性wmctrl -l
:列表始终列出窗口按照创建顺序。
这意味着如果您有(例如)三个窗口,并且始终按照相同的顺序重新创建,那么您可以简单地先过滤掉属于的窗口Chrome
,然后按照它们在 的输出中出现的顺序“标记”这些窗口wmctrl
。
如何Chrome
从 wmctrl 中过滤掉窗口
要识别属于应用程序的窗口,您需要使用以下命令:
wmctrl -lp
这也将显示进程号窗口所属的。通常,这是一个单身的pid。但是,在这种情况下Chrome
,将会有多个。从编程上讲,该过程如下:
Chrome
通过运行以下命令查找 pid :pgrep chrome
运行命令:
wmctrl -lp
解析每个窗口所属的 pid,并在输出(列表)中查找匹配项
pgrep chrome
这将生成属于 的窗口列表
Chrome
。如前所述,它们的标识是它们在列表中的顺序。然后您需要做的就是解析它们的窗口 ID(wmctrl -lp
您运行的输出中它们行中的第一个字符串),然后就完成了。
随后,使用常用命令将窗口移动到所需的工作区。
一个例子;测试
作为示例脚本来测试这是否有效(python,还有什么:))
#!/usr/bin/env python3
import subprocess
# get the list of pids of chrome
pids = [p for p in subprocess.check_output(["pgrep", "chrome"]).decode("utf-8").splitlines()]
# get the list of windows
windows = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8").splitlines()]
# filter out the windows of chrome, parse their window-id
matches = [w[0] for w in windows if w[2] in pids]
print(matches)
# raise the window
subprocess.Popen(["wmctrl", "-ia", matches[0]])
对于这个例子,我打开了三个Chrome
窗口,按照你描述的方式关闭它们,然后Chrome
再次打开。
在matches[0]
(最后一行),我让它提升列表的第一个窗口:
['0x05600001', '0x05600039', '0x0560003a']
在下一次运行时,窗口 ID 发生了改变:
['0x05800001', '0x05800039', '0x0580003a']
但它们在列表中的顺序保持不变,因为(实际上)窗口总是按照相同的(时间顺序)顺序创建。因此脚本的最后一行:
subprocess.Popen(["wmctrl", "-ia", matches[0]])
总是使同一个(第一个)窗口升起,而
subprocess.Popen(["wmctrl", "-ia", matches[1]])
总是会提高第二个等等。
用 move- 命令替换 raise- 命令,你的脚本就可以正常工作了。
答案2
所以我能够使用 Python 解决这个问题。请记住,这是我的第一个 Python 脚本,因此它并不完美。
#!/usr/bin/python
import subprocess
foo=subprocess.check_output(["wmctrl", "-lx"]) #list windows with WM_CLASS
def f1(foo=foo): return iter(foo.splitlines())
list=list(f1());
gloop=0 #google loop - to count google windows
sloop=0 #sublime loop - to count sublime windows (currently only one, but I might add more in future)
google = [ ["0", "0"], ["2000", "0"], ["2000", "2000"], ["2000", "0"] ] #google windows positioning
sublime = [ ["2000", "0"] ] #sublime windows positioning
for s in list:
if (s[14:20]=='Google'):
#print "Google"
windowid=s[0:10]
windowpos="0,"+google[gloop][0]+","+google[gloop][1]+",-1,-1"
subprocess.call(["wmctrl", "-r", windowid, "-i", "-e", windowpos]);
gloop+=1
if (s[14:20]=='sublim'):
#print "Sublime_text"
windowid=s[0:10]
windowpos="0,"+sublime[sloop][0]+","+sublime[sloop][1]+",-1,-1"
subprocess.call(["wmctrl", "-r", windowid, "-i", "-e", windowpos]);
sloop+=1