web-dev-qa-db-fra.com

Comment puis-je éviter que l'espace de travail ne soit gênant et que la fenêtre se chevauche?

Dans l'espace de travail actuel, je ne veux pas voir le bord d'une fenêtre avec laquelle je travaillais sur un autre espace de travail.

J'aime aussi pouvoir pousser une fenêtre principalement hors écran, donc forcer les limites ne serait pas une bonne solution.

Existe-t-il un moyen de ne pas afficher une fenêtre si elle ne fait pas partie de l'espace de travail actuel?

2
Seph Reed

Comment empêcher l'espace de travail - les fenêtres qui se chevauchent

Je crois que la solution ci-dessous fait ce que vous décrivez. C'est ce que ça fait:

L'effet habituel: des fenêtres qui se chevauchent apparaîtront sur les espaces de travail adjacents

enter image description here

Effectivement, lorsque vous appuyez sur une combinaison de touches, ce sera le résultat

enter image description here

En pratique:

Un exemple

  • Travailler sur (par exemple) l'espace de travail 1, certaines fenêtres se chevauchant sur d'autres espaces de travail
  • Passez ensuite à l'espace de travail 2, appuyez sur la combinaison de touches de raccourci: toutes les fenêtres, à l'exception de celles de l'espace de travail actuel, seront réduites au minimum et n'apparaîtront donc pas sur l'espace de travail actuel de toute façon (sauf pour le lanceur).
  • Revenant ensuite à l'espace de travail 1, en appuyant à nouveau sur la combinaison de touches, le bureau sera exactement comme vous l'avez laissé. Même l'ordre des fenêtres (z-sage) et éventuellement les fenêtres minimisées seront exactement tels qu'ils étaient. Dans le même temps, les fenêtres sur autres que l'espace de travail actuel seront masquées.

Comment ça fonctionne

La solution comprend deux scripts; un script d'arrière-plan, qui garde la trace de l'ordre z des fenêtres (puisque nous n'avons pas d'outils pour l'obtenir autrement), et un script pour minimiser les fenêtres et suivre quelles fenêtres déjà été minimisé par l'utilisateur .

Pourquoi deux scripts?

Au début, j'avais le script combiné en un, et cela semblait bien fonctionner. Cependant, sur mon système, il a augmenté l'occupation du processeur (inactif) de 3-4% à environ. 9-11%, ce qui est trop pour un script d'arrière-plan à mon avis, surtout lorsque vous exécutez plusieurs scripts en même temps.
Le script est maintenant divisé en une section d'arrière-plan qui garde une trace sur l'historique de focus (pour pouvoir minimiser les fenêtres dans le même ordre z que vous avez quitté l'espace de travail), et un script à appeler avec un raccourci clavier. Le script d'arrière-plan n'ajoute pratiquement aucun bruit de fond.

Comment installer

  1. Les scripts nécessitent à la fois wmctrl et xdotool:

    Sudo apt-get install wmctrl xdotool
    
  2. Copiez script1 ci-dessous dans un fichier vide, sauvegardez-le comme 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. Copiez le script2 ci-dessous dans un fichier vide, sauvegardez-le comme 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. Testez- exécutez la configuration: avant d'ouvrir toutes les autres fenêtres:

    • Exécutez script1 à partir d'une fenêtre de terminal par la commande:

      python3 /path/to/focus_history.py
      
    • Maintenant, ouvrez des fenêtres aléatoires, certaines chevauchant vos espaces de travail

    • Maintenant, passez à l'espace de travail adjacent, exécutez le script 2 avec la commande:

      python3 /path/to/stop_overlap.py
      

    Les fenêtres qui se chevauchent devraient disparaître

    • Revenez au premier espace de travail, exécutez à nouveau la dernière commande, votre espace de travail doit être restauré exactement comme il était

Si tout fonctionne correctement, ajoutez script1 aux applications de démarrage: Dash> Applications de démarrage> Ajouter. Ajoutez la commande:

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

Ajoutez script2 à une touche de raccourci: choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez la commande:

python3 /path/to/stop_overlap.py

vers un raccourci de votre choix ...

1
Jacob Vlijm