Puis-je réduire une fenêtre dans une boîte sur Unity?

17

Sur le 4Dwm d'Irix, il y avait une possibilité de minimiser les fenêtres dans une boîte (contrairement à la barre des tâches utilisée par les gestionnaires de fenêtres modernes). J'ai vu cela aussi sur un vieux HPUX.

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

entrez la description de l'image ici

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

Artium
la source
Question étrange mais intéressante :) Je pourrais penser à quelque chose comme ça. L'icône importerait-elle ou pourrait-elle être générique? Comment se comporte-t-il? comme une icône sur le bureau ou une "fenêtre" minimale.
Jacob Vlijm
@JacobVlijm L'icône n'est pas générique. Chaque application a sa propre icône comme les icônes des fenêtres réduites dans Unity)
Artium
Cela pourrait également être fait dans Unity, mais la fenêtre serait iconisée sur le bureau (avec l'icône de l'application correspondante et le nom de la fenêtre). Envie d'un coup? (ce serait un travail intéressant, mais difficile, mieux vaut demander avant de commencer :))
Jacob Vlijm
1
Oui, cela peut m'aider. Je dois travailler avec beaucoup de fenêtres ouvertes et cette façon de les organiser est meilleure à mon avis. Je ne connais rien sur Unity, donc je ne peux aider qu'avec les tests.
Artium

Réponses:

18

À ma grande surprise, cela fonctionne très bien, tant que vous n'avez pas trop d'autres choses sur votre bureau .

J'ai travaillé avec pendant un certain temps, et cela semble une alternative étrange, mais assez intéressante aux commutateurs d'espace de travail fréquents. Rafraîchissant pour sa simplicité.

En pratique

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

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

    entrez la description de l'image ici

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

    entrez la description de l'image ici

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

Comment ça fonctionne

L'histoire courte (explication):

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

    windowbox box
    
  • Le script ensuite:

    • lit l'id de la fenêtre 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 .desktopfichier de l'application correspondante dans/usr/share/applications
    • crée un .desktopfichier au nom unique , avec une Exec=ligne qui appelle le script (lorsque vous double-cliquez dessus) avec l'argument show:

      windowbox show
      

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

Par la suite:

  • Le .desktopfichier est ensuite rendu exécutable, pour en faire un objet double-cliquable.

  • Lorsque le .desktopfichier est double-cliqué, la fenêtre est (re) mappée, le .desktopfichier est supprimé de votre bureau.

Comment installer

  1. Comme pratiquement toujours, lorsque vous voulez jouer avec Windows, le script a besoin des deux wmctrlet 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 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 faire apparaître le répertoire nouvellement créé $PATH, déconnectez-vous ou ouvrez-le source ~/.profile(à partir d'une fenêtre de terminal)
  6. Testez-exécutez le script à partir d'une fenêtre de terminal par la commande:

    windowbox box
    

    La fenêtre devrait disparaître, la fenêtre "encadrée" devrait apparaître sur votre bureau.

  7. Si tout fonctionne bien, ajoutez la commande suivante à une touche de raccourci: choisissez l'icône d'engrenage en haut à droite de votre écran:

    Icône d'engrenage

  8. Allez à System SettingsKeyboardShortcutsCustom Shortcuts. Cliquez sur +et ajoutez la commande:

    windowbox box
    

Ça devrait le faire.

Note importante

Le script utilise xdotool' windowunmappour rendre la fenêtre invisible. La "boîte" (icône) 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 [modifier 20-12: terminé ]

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 réparé, mais j'ai pensé 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 cependant bénéficier d'une certaine amélioration. 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 de la fenêtre encadrée une taille différente de celle des autres icônes

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

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, la taille est mémorisée. Même si vous recréez le fichier après un redémarrage. Cela signifie que si vous jamais redimensionnée les fenêtres en boîte (par exemple) 1-5, ils toujours la même taille lorsque vous (le script) les créer à nouveau!

entrez la description de l'image ici

Jacob Vlijm
la source
2
Je ne peux pas me résister sans laisser de commentaire, très belle réponse de votre part :)
Ravan
Agréable! Quelques commentaires: 1. J'ai remplacé la ligne dtop = "/home/jacob/Bureaublad"par un chemin vers mon bureau ( dtop = "/home/" + user + "/Desktop") 2. La restauration en double-cliquant n'a pas fonctionné. Je soupçonne que ce source ~/.profilen'est pas suffisant se connectera / se déconnectera rapidement pour tester tester cela. 3. Dans l'unité, il est possible de redimensionner les icônes manuellement (clic droit -> icône de redimensionnement), est-il possible d'ajouter un paramètre f_contentpour définir la taille de l'icône?
Artium
4
Quand j'ai commencé à lire le premier paragraphe de cette réponse, je savais juste qu'il y aurait une icône orange en bas! ;-): P
Fabby
1
Salut @Artium J'ai mis à jour le script, il a maintenant quelques améliorations importantes, y compris une meilleure recherche d'icônes et une meilleure restauration de la géométrie, Amusez-vous!
Jacob Vlijm
1
@Artium, je sais, mais essayez celui du script, c'est l'icône de dossier habituelle, similaire à votre image. probablement juste un lien vers la même icône.
Jacob Vlijm
7

Vous pouvez utiliser fvwm pour accomplir cela.

  1. Installez fvwm:

    sudo apt-get update
    sudo apt-get install fvwm
    
  2. Trouvez-en un qui utilise 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/(afficher 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 et sélectionnez fvwm et connectez-vous.

entrez la description de l'image ici

Mateo
la source