我正在运行一个脚本wmctrl -x -a "$1"
。它会弹出一个窗口,作为参数传递给脚本,例如:
wmctrl -x -a "Firefox"
激活 Firefox。
然而,对于有多个窗口的应用程序,它不会调出最后的使用的窗口。假设我在 中打开了 3 个窗口LibreOffice Writer
,分别名为“文档 1”、“文档 2”和“文档 3”,我现在在文档 3 上,然后转到另一个应用程序。执行脚本会显示“文档 1”,而不是上次使用的“文档 3”。
有没有什么标志可以解决这个问题wmctrl
?
答案1
根据要求,分离出另一个答案,并补充一个新的部分。
窗口的焦点历史记录
如何提升应用程序最近聚焦的窗口
正如我在评论中提到的,目前没有窗口的焦点历史记录。这意味着如果我们需要它,我们需要自己创建它。下面的第一个脚本正是这样做的;它跟踪当前聚焦的窗口,并将历史记录存储在一个小文件中,每秒刷新一次。行的顺序也是焦点的顺序;顶行代表最新的聚焦窗口,最后一行代表“最旧的”。
要使脚本调出应用程序最近聚焦的窗口,我们需要做的就是从上到下阅读这些行,找到应用程序窗口的第一个出现位置,然后调出它。如果您使用所WM_CLASS
寻找窗口的 运行第二个脚本,那么它正是这样做的。
脚本
后台脚本,跟踪焦点历史记录。此脚本与第一个脚本完全相同这里:
#!/usr/bin/env python3 import subprocess import time import os rootdata = os.environ["HOME"]+"/.focus_history" open(rootdata, "wt").write("This is an empty line") def current_windows(): try: return subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8") except subprocess.CalledProcessError: pass def convert_format(w_id): return w_id[:2]+(10-len(w_id))*"0"+w_id[2:] def read_data(): return open(rootdata).read().splitlines() def get_top(wlist): try: top = convert_format( [l.split("#")[-1].strip() for l in subprocess.check_output( ["xprop", "-root"] ).decode("utf-8").splitlines() \ if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0]) return [l for l in wlist if top in l][0] except IndexError: pass if __name__ == "__main__": while True: time.sleep(1) wdata = current_windows() if wdata != None: wlist = wdata.splitlines() # get frontmost window (as in wmctrl -lG) top = get_top(wlist) oldlist = read_data() if not any([top == oldlist[0], top == None]): # clean up closed windows [oldlist.remove(l) for l in oldlist if not l.split()[0] in wdata] # remove possible other mentions of the active window [oldlist.remove(l) for l in oldlist if l.startswith(top.split()[0])] open(rootdata, "wt").write(("\n").join([top]+oldlist))
将脚本复制到一个空文件中,另存为
focus_history.py
用于提升应用程序最新焦点窗口的脚本。
#!/usr/bin/env python3 import os import subprocess import sys lookfor = sys.argv[1] winhistory = os.environ["HOME"]+"/.focus_history" for l in open(winhistory): wid = l.split()[0] wmclass = subprocess.check_output( ["xprop", "-id", wid, "WM_CLASS"] ).decode("utf-8").strip() if lookfor in wmclass: subprocess.check_output(["wmctrl", "-ia", wid]) break
另存为
raise_recent.py
。
如何使用
确保
wmctrl
已安装:sudo apt install wmctrl
使用以下命令在后台测试运行第一个脚本:
python3 /path/to/focus_history.py
注意:确保脚本启动前其他窗口打开,否则窗口只有在获得第一个焦点后才会被记录(当然)。
使用命令调用第二个脚本(例如)
python3 /path/to/raise_recent.py gedit
...调出最近聚焦的窗口
gedit
。如果一切正常,请将第一个脚本添加到启动应用程序。但请注意,您可能需要在脚本启动前添加一个中断,以防止
wmctrl
中断。(尽管脚本不应该这样做,因为它处理可能的异常)。
就是这样。