web-dev-qa-db-ja.com

煩わしいワークスペースとウィンドウの重なりを防ぐにはどうすればよいですか?

現在のワークスペースでは、別のワークスペースで作業していたウィンドウの端を表示したくありません。

また、私はウィンドウをほとんど画面の外に押し出すことができるので、境界を強制することは良い解決策ではないでしょう。

現在のワークスペースの一部ではない場合、ウィンドウを表示しない方法はありますか?

2
Seph Reed

ワークスペースが重なり合うウィンドウを防ぐ方法

以下の解決策はあなたが説明したことを実行していると思います。これはそれがすることです:

通常の効果:重なり合うウィンドウが隣接するワークスペースに表示されます

enter image description here

事実上、キーの組み合わせを押すと、これが結果になります

enter image description here

実際には:

  • (例)ワークスペース1で作業していて、一部のウィンドウが他のワークスペースと重なっている
  • 次に、ワークスペース2に移動し、ショートカットキーの組み合わせを押します。現在のワークスペース上のウィンドウを除くすべてのウィンドウが最小化され、現在のワークスペースには表示されません(ただし、ランチャー用)。
  • 次に、ワークスペース1に戻り、キーの組み合わせをもう一度押すと、デスクトップは正確にそのままになります。ウィンドウの順序(z方向)と最小化されたウィンドウでさえも正確にになります。同時に、現在のワークスペース以外のother上のウィンドウは非表示になります。

使い方

ソリューションには2つのスクリプトが含まれています。ウィンドウのzオーダーを追跡する1つのバックグラウンドスクリプト(他の方法で取得するためのツールがないため)、およびウィンドウを最小化して既に追跡されているウィンドウを追跡するスクリプトユーザーによって最小化されます

2つのスクリプトを使用する理由

最初はスクリプトを1つにまとめていましたが、問題なく動作したようです。しかし、私のシステムでは、(アイドル)プロセッサの占有率が3〜4%からapprに増加しました。 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. セットアップをテスト実行します:before他のウィンドウを開く前に:

    • 次のコマンドを使用して、ターミナルウィンドウからscript1を実行します。

      python3 /path/to/focus_history.py
      
    • いくつかのランダムなウィンドウを開いて、いくつかはワークスペースと重なります

    • 次に隣接するワークスペースに移動し、次のコマンドでスクリプト2を実行します。

      python3 /path/to/stop_overlap.py
      

    重なっているウィンドウが消えるはずです

    • 最初のワークスペースに戻り、最後のコマンドを再度実行すると、ワークスペースは完全に復元されます

すべて正常に機能する場合は、script1をスタートアップアプリケーションに追加します。ダッシュ>スタートアップアプリケーション>追加。次のコマンドを追加します。

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

Script2をショートカットキーに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。 「+」をクリックして、コマンドを追加します。

python3 /path/to/stop_overlap.py

お好みのショートカットに...

2
Jacob Vlijm