如何才能避免出现令人厌烦的工作区重叠窗口?

如何才能避免出现令人厌烦的工作区重叠窗口?

在当前工作区中,我不想看到我在另一个工作区上工作的窗口的边缘。

另外,我喜欢将窗口推离屏幕,因此强制界限不是一个好的解决方案。

如果窗口不是当前工作区的一部分,有没有办法不显示它?

答案1

如何防止工作区窗口重叠

我相信下面的解决方案可以实现您所描述的功能。它的作用如下:

通常的效果:重叠的窗口将出现在相邻的工作区上

在此处输入图片描述

实际上,按下组合键时,结果如下

在此处输入图片描述

在实践中:

一个例子

  • 在(例如)工作区 1 上工作,其中一些窗口与其他工作区重叠
  • 然后移动到工作区 2,按下快捷键组合:除当前工作区上的窗口外,所有窗口都将最小化,因此不会出现在当前工作区中无论如何(除了启动器)。
  • 然后返回工作区 1,再次按下组合键,桌面将确切地就像你离开时一样。甚至窗口顺序(z 方向)和可能最小化的窗口都将确切地就像以前一样。与此同时,窗户其他则当前工作区将被隐藏。

怎么运行的

该解决方案包括两个脚本;一个是后台脚本,用于跟踪窗口的 z 顺序(因为我们没有其他工具来获取它);另一个脚本用于最小化窗口并跟踪哪些窗口已被用户最小化

为什么要有两个脚本?

最初,我将脚本合并为一个,它似乎运行良好。但是,在我的系统上,它将(空闲)处理器占用率从 3-4% 增加到大约 9-11%,在我看来,这对于后台脚本来说太多了,尤其是当您同时运行多个脚本时。
该脚本现在分为一个后台部分,用于跟踪焦点历史记录(以便能够以与离开工作区相同的 z 顺序取消最小化窗口),以及一个使用键盘快捷键调用的脚本。后台脚本几乎不会增加背景噪音。

如何设置

  1. 脚本需要wmctrlxdotool

    sudo apt-get install wmctrl xdotool
    
  2. 将下面的 script1 复制到一个空文件中,并将其保存为focus_history.py

    #!/usr/bin/env python3
    import subprocess
    import time
    import os
    
    rootdata = os.environ["HOME"]+"/.focus_history"
    
    def current_windows():
        try:
            return subprocess.check_output(["wmctrl", "-l"]).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
    
    open(rootdata, "wt").write("This is an empty line")
    
    while True:
        time.sleep(0.5)
        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))
    
  3. 将下面的 script2 复制到一个空文件中,并将其保存为stop_overlap.py

    #!/usr/bin/env python3
    import subprocess
    import time
    import os
    
    wfile = os.environ["HOME"]+"/.m_list"
    rootdata = os.environ["HOME"]+"/.focus_history"
    
    def get_res():
        # get the resolution (workspace- size)
        data = subprocess.check_output(["xrandr"]).decode("utf-8").split()
        mark = data.index("current")
        return [int(n) for n in [data[mark+1], data[mark+3].replace(",", "")]]
    
    res =  get_res()
    
    def get_wlist(res):
        try:
            # get the window data
            wlist = [l.split() for l in subprocess.check_output(
                ["wmctrl", "-lG"]).decode("utf-8").splitlines()]
            # check if windows are "normal" windows and see if they are minimized
            show = []; hide = []
            for w in wlist:
                w_data = subprocess.check_output(
                    ["xprop", "-id", w[0]]
                    ).decode("utf-8")
                quality = [
                    "_NET_WM_WINDOW_TYPE_NORMAL" in w_data,
                    "_NET_WM_STATE_HIDDEN" in w_data,
                    ]
                # check if windows are on current workspace or elsewhere
                onthis = all([0 < int(w[2]) < res[0],
                        0 < int(w[3]) < res[1]])
                # summarize what should be done with the windows
                if all([quality == [True ,True], onthis == True]):
                    show.append(w[0])
                elif all([quality == [True, False], onthis == False]):
                    hide.append(w[0])
            return [show, hide, [l[0] for l in wlist]]
        except subprocess.CalledProcessError:
            pass
    
    oncurrent = []; onother = []; d_wlist = []
    wins = get_wlist(res)
    
    for w in wins[1]:
        # hide (minimize) windows on other workspacec -only if- they are not hidden already!
        subprocess.Popen(["xdotool", "windowminimize", w])
        # write hidden windows to a file, so the script will only un- minimize windows
        # that were not hidden in the first place
        open(wfile, "a+").write("\n"+w)
    if wins[0]:
        # if there are windows on the current workspace that need to be un- minimized,
        # show them in the correct z- order, as recorded by the other script
        priority = reversed([l.split()[0] for l in open(rootdata).read().splitlines()])
        try:
            d_wlist = [l for l in open(wfile).read().splitlines() if not l == "\n"]
        except FileNotFoundError:
            d_wlist = []
        for w in priority:
            if all([w in wins[0], w in d_wlist]):
                subprocess.Popen(["wmctrl", "-ia", w])
                time.sleep(0.1)
                d_wlist.remove(w)
        # clean up window list, remove non- existant windows
        d_wlist = set([item for item in d_wlist if item in wins[2]])
        open(wfile, "wt").write(("\n").join(d_wlist))
    
  4. 测试运行设置: 打开任何其他窗口:

    • 使用以下命令从终端窗口运行 script1:

      python3 /path/to/focus_history.py
      
    • 现在打开一些随机窗口,一些与你的工作区重叠

    • 现在移动到相邻的工作区,使用以下命令运行脚本 2:

      python3 /path/to/stop_overlap.py
      

    重叠的窗口应该消失

    • 回到第一个工作区,再次运行最后一个命令,你的工作区应该恢复和以前一模一样

如果一切正常,请将 script1 添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

/bin/bash -c "sleep 15 && python3 /path/to/focus_history.py

将script2添加为快捷键:选择:系统设置>“键盘”>“快捷键”>“自定义快捷键”,点击“+”,添加命令:

python3 /path/to/stop_overlap.py

到您选择的快捷方式...

相关内容