web-dev-qa-db-fra.com

Puis-je minimiser une fenêtre dans une boîte sur Unity?

Sur le logiciel 4Dwm d'Irix, il était possible de réduire les fenêtres dans une boîte (contrairement à la barre des tâches utilisée par les gestionnaires de fenêtres modernes). Je l'ai vu aussi sur un vieux HPUX.

Voir le carré "console" dans l'image liée:

enter image description here

Est-il possible d'accomplir sur Ubuntu, avec un plugin ou peut-être un gestionnaire de fenêtres autre que Unity?

17
Artium

À ma propre surprise, cela fonctionne assez bien, Tant que vous n'avez pas trop d'autres choses sur votre bureau .

Cela fait un moment que je travaille dessus et cela semble étrange, mais assez étrange , une alternative intéressante aux fréquents changements d’espace de travail. Rafraîchissant pour sa simplicité.

En pratique

La solution est en réalité à peu près ce que vous décrivez:

  • En appuyant sur une combinaison de touches, vous "cliquerez" la fenêtre sur votre bureau à partir d'une fenêtre:

    enter image description here

    dans une icône, avec l'apparence de l'application:

    enter image description here

  • Double-cliquez sur l'icône. La fenêtre réapparaîtra et l'icône disparaîtra.

Comment ça fonctionne

La nouvelle (explication):

  • Lorsque vous appuyez sur la touche de raccourci, le script est appelé avec l'argument box:

    windowbox box
    
  • Le script alors:

    • lit l'identifiant de la fenêtre la plus en avant
    • vérifie s'il s'agit d'une fenêtre "normale" (vous ne voudriez pas démapper votre bureau par exemple)
    • Recherche le nom du processus de l'application, propriétaire de la fenêtre.
    • Recherche l'icône correspondante dans le fichier .desktop de l'application correspondante dans /usr/share/applications.
    • crée un fichier .desktop uniquement nommé, avec une ligne Exec= qui appelle le script (lorsque vous double-cliquez dessus) avec l'argument show:

      windowbox show
      

Le fichier .desktop ajoutera un certain nombre d'arguments supplémentaires, tels que l'id de la fenêtre, le nom (fichier) du fichier .desktop.

Par la suite:

  • Le fichier .desktop est alors rendu exécutable, ce qui en fait un objet double-cliquable.

  • Lorsque vous double-cliquez sur le fichier .desktop, la fenêtre est (re) mappée, le fichier .desktop est supprimé de votre bureau.

Comment mettre en place

  1. Comme toujours, lorsque vous voulez jouer avec Windows, le script a besoin de wmctrl et de xdotool:

    Sudo apt-get install xdotool wmctrl
    
  2. Créez le répertoire ~/bin (~ représente votre répertoire personnel)
  3. Copiez le script ci-dessous dans un fichier vide, enregistrez-le sous le nom windowbox (sans extension) dans ~/bin.

    #!/usr/bin/env python3
    import subprocess
    import sys
    import os
    
    # --- On Unity, there is a (y-wise) deviation in window placement
    # set to zero for other window managers
    deviation = 28
    # ---
    
    args = sys.argv[1:]
    
    get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()
    
    def find_dtop():
        # get the localized path to the Desktop folder
        home = os.environ["HOME"]
        dr_file = home+"/.config/user-dirs.dirs"
        return [home+"/"+ l.split("/")[-1].strip() \
                for l in open(dr_file).readlines() \
                if l.startswith("XDG_DESKTOP_DIR=")][0].replace('"', "")
    
    def check_windowtype(w_id):
        # check the type of window; only unmap "NORMAL" windows
        return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])
    
    def get_process(w_id):
        # get the name of the process, owning the window and window x/y position
        w_list = get(["wmctrl", "-lpG"]).splitlines()
        pid = [l for l in w_list if w_id in l][0].split()
        proc = get(["ps", "-p", pid[2], "-o", "comm="])
        xy = (" ").join(pid[3:5])
        return (proc, xy)
    
    def read_f(f, string, proc):
        # search for a possible match in a targeted .desktop file
        try:
            with open(f) as read:
                for l in read:
                    if all([l.startswith(string), proc in l]):
                        in_f = True
                        break
                    else:
                        in_f = False
        except:
            in_f = False
        return in_f
    
    def get_icon(proc, w_name):
        # search appropriate icon in /usr/share/applications
        exceptions = [item for item in [
            ["soffice", "libreoffice-main"],
            ["gnome-terminal", "utilities-terminal"],
            ["nautilus", "folder"],
            ] if item[0] in proc]
        if exceptions:
            if exceptions == [["soffice", "libreoffice-main"]]:
                loffice = [
                    ["Calc", "libreoffice-calc"],
                    ["Writer", "libreoffice-writer"],
                    ["Base", "libreoffice-base"],
                    ["Draw", "libreoffice-draw"],
                    ["Impress", "libreoffice-impress"],
                    ]
                match = [m[1] for m in loffice if m[0] in w_name]
                if match:
                    return match[0]
                else:
                    return exceptions[0][1]
            else:      
                return exceptions[0][1]
        else:
            default = "/usr/share/applications"
            dtfiles = [default+"/"+f for f in os.listdir(default)]
            for f in dtfiles:
                if read_f(f, "Exec=", proc) == True:   
                    for l in open(f).readlines():
                        if l.startswith("Icon="):
                            icon = l.replace("Icon=", "").strip()
                            print(f)
                            break
                    break
            return icon
    
    def create_name():
        # create unique (file-) name for boxed window
        n = 1
        while True:
            name = dtop+"/"+"boxed_"+str(n)+".desktop"
            if os.path.exists(name):
                n += 1
            else:
                break
        return name
    
    def convert_wid(w_id):
        # convert window- id, xdotool format, into wmctrl format
        w_id = hex(int(w_id))
        return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]
    
    def create_icon(w_id, w_name, icon, pos):
        # create the launcher, representing the boxed window
        boxedwindow = create_name()
        f_content =[
                "[Desktop Entry]",
                "Name=[WINDOW] "+w_name,
                "Exec=windowbox show "+w_id+" '"+boxedwindow+"' "+pos,
                "Icon="+icon,
                "Type=Application",
                ]
        if icon == "generic":
            f_content.pop(3)
        with open(boxedwindow, "wt") as boxed:
            for l in f_content:
                boxed.write(l+"\n")
        command = "chmod +x "+"'"+boxedwindow+"'"
        subprocess.call(["/bin/bash", "-c", command])
    
    if args[0] == "box":
        dtop = find_dtop()
        w_id = convert_wid(get(["xdotool", "getactivewindow"]))
        w_name = get(["xdotool", "getwindowname", w_id])
        if check_windowtype(w_id) == True:
            procdata = get_process(w_id)
            procname = procdata[0]
            icon = get_icon(procname, w_name); icon = icon if icon != None else "generic"
            create_icon(w_id, w_name, icon, procdata[1])
            subprocess.call(["xdotool", "windowunmap", w_id])
    
    Elif args[0] == "show":
        w_id = args[1]
        subprocess.call(["xdotool", "windowmap", w_id])    
        subprocess.call(["xdotool", "windowmove", "--sync", w_id, args[3], str(int(args[4])-deviation)])
        os.remove(args[2])
    
  4. Rendre le script exécutable

  5. Pour que le répertoire nouvellement créé "apparaisse" dans $PATH, vous devez soit vous déconnecter/entrer, soit exécuter source ~/.profile (à partir d'une fenêtre de terminal)
  6. Test: lancez le script à partir d'une fenêtre de terminal à l'aide de la commande suivante:

    windowbox box
    

    La fenêtre devrait disparaître, la fenêtre "en boîte" devrait apparaître sur votre bureau.

  7. Si tout fonctionne correctement, ajoutez la commande suivante à une touche de raccourci: choisissez l’icône représentant un engrenage en haut à droite de votre écran:

    Gear icon

  8. Aller à System Settings → Keyboard → Shortcuts → Custom Shortcuts. Clique le + et ajoutez la commande:

    windowbox box
    

Ça devrait le faire.

Note importante

Le script utilise xdotool 'windowunmap pour rendre la fenêtre invisible. La "boîte" créée sur votre bureau est la seule "porte" vers la fenêtre cachée. En d'autres termes: ne supprimez pas le (s) fichier (s) de bureau manuellement. La fenêtre sera définitivement perdue si vous le faites.

Travail à faire [edit 20-12: done ]

Le script pourrait encore utiliser un raffinement:

  • La géométrie de la fenêtre n'est pas restaurée par définition. Peut être très bien corrigé, mais je pensais vous montrer le premier résultat.
  • Dans la plupart des cas, la fenêtre encadrée a son icône correcte. La fonction get_process(w_id) pourrait toutefois être améliorée. Si le processus n'est pas trouvé en tant que commande dans /usr/share/applications, le fichier a une icône générique.

Donner aux icônes boxed-window une taille différente de celle des autres icônes

Le script nomme les fichiers .desktop créés toujours boxed_1.desktop, boxed_2.desktop etc, en fonction du nom "disponible" au moment de la création ( noms de fichiers, pas le nom affiché).

Vous pouvez redimensionner les fichiers (en général), par un clic droit> taille de l'icône. La bonne nouvelle est que si vous supprimez le fichier et le recréez, sa taille est mémorisée. Même si vous créez à nouveau le fichier après un redémarrage. Cela signifie que si vous redimensionniez les fenêtres encadrées (par exemple) 1-5, elles auront toujours la même taille lorsque (le script) les recréer!

enter image description here

18
Jacob Vlijm

Vous pouvez utiliser fvwm pour accomplir cela.

  1. Installez fvwm:

    Sudo apt-get update
    Sudo apt-get install fvwm
    
  2. Trouvez-les qui utilisent la fonction iconify - il y en a plusieurs ici: http://www.jmcunx.com/fvwm_theme.html Plusieurs ressemblent à la capture d'écran que vous montrez.

  3. Copiez le texte du thème, puis accédez à ~/.fvwm/ (affichez d’abord les fichiers cachés), puis créez un fichier .fvwm2rc

  4. Ouvrez ce fichier dans un éditeur de texte (comme gedit) et collez-y le texte du thème.

  5. Redémarrez l'ordinateur, sélectionnez fvwm et connectez-vous.

enter image description here

7
Mateo