¿Puedo minimizar una ventana en un cuadro en Unity?

17

En el 4Dwm de Irix, había una capacidad de minimizar las ventanas en una caja (al contrario de la barra de tareas utilizada por los administradores de ventanas modernos). He visto esto también en un viejo HPUX.

Vea el cuadro "consola" en la imagen vinculada:

ingrese la descripción de la imagen aquí

¿Es posible lograrlo en Ubuntu, ya sea con un complemento o tal vez algún administrador de ventanas que no sea Unity?

Artium
fuente
Pregunta extraña pero interesante :) Podría pensar en algo como esto. ¿Importaría el icono o podría ser genérico? ¿Cómo se comporta? como un ícono en el escritorio o una "ventana" mínima.
Jacob Vlijm
@JacobVlijm El icono no es genérico. Cada aplicación tiene su propio ícono como íconos de ventanas minimizadas en Unity)
Artium
También se podría hacer dentro de Unity, pero la ventana estaría iconizada en el escritorio (con el icono de la aplicación correspondiente y el nombre de la ventana). ¿Te apetece un tiro? (sería un trabajo interesante pero desafiante, mejor pregunte antes de comenzar :))
Jacob Vlijm
1
Sí, esto puede ser útil para mí. Tengo que trabajar con muchas ventanas abiertas y esta forma de organizarlas es mejor en mi opinión. No sé nada sobre Unity, por lo que solo puedo ayudar con las pruebas.
Artium

Respuestas:

18

Para mi sorpresa, funciona bastante bien, siempre y cuando no tenga muchas otras cosas en su escritorio .

Trabajé con él durante un tiempo, y parece una alternativa extraña, pero extrañamente buena para los frecuentes cambios de espacio de trabajo. Refrescante por su simplicidad.

En la práctica

La solución es más o menos lo que usted describe:

  • Al presionar una combinación de teclas se "encajonará" la ventana en su escritorio, desde una ventana:

    ingrese la descripción de la imagen aquí

    en un icono, con la apariencia de la aplicación:

    ingrese la descripción de la imagen aquí

  • Haga doble clic en el icono, y la ventana volverá a aparecer y el icono desaparecerá.

Cómo funciona

La historia corta (explicación):

  • Al presionar la tecla de acceso directo, se llama al script con el argumento box:

    windowbox box
    
  • El guión entonces:

    • lee la identificación de la ventana de la ventana frontal
    • comprueba si es una ventana "normal" (por ejemplo, no querrás desasignar tu escritorio)
    • Busca el nombre del proceso de la aplicación, que posee la ventana.
    • Busca el icono correspondiente en el .desktoparchivo de la aplicación correspondiente en/usr/share/applications
    • crea un .desktoparchivo con un nombre único , con una Exec=línea que llama al script (cuando se hace doble clic) con el argumento show:

      windowbox show
      

El .desktoparchivo agregará una serie de argumentos de argumentos adicionales, como la identificación de la ventana, el nombre (archivo) del .desktoparchivo.

Después:

  • El .desktoparchivo se hace ejecutable, para convertirlo en un objeto de doble clic.

  • Cuando .desktopse hace doble clic en el archivo, la ventana se (re) asigna, el .desktoparchivo se elimina de su escritorio.

Como instalar

  1. Como prácticamente siempre, cuando quieres jugar con Windows, el script necesita ambos wmctrly xdotool:

    sudo apt-get install xdotool wmctrl
    
  2. Cree el directorio ~/bin( ~significa su directorio de inicio)
  3. Copie el script a continuación en un archivo vacío, guárdelo como windowbox(sin extensión) en ~/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. Hacer el script ejecutable

  5. Para hacer que el directorio recién creado "aparezca" $PATH, cierre sesión / inicie sesión o ejecútelo source ~/.profile(desde una ventana de terminal)
  6. Prueba: ejecute el script desde una ventana de terminal con el comando:

    windowbox box
    

    La ventana debería desaparecer, la ventana "en caja" debería aparecer en su escritorio.

  7. Si todo funciona bien, agregue el siguiente comando a una tecla de acceso directo: elija el icono de engranaje en la parte superior derecha de la pantalla:

    Icono de engranaje

  8. Ir a System SettingsKeyboardShortcutsCustom Shortcuts. Haga clic en +y agregue el comando:

    windowbox box
    

Deberias hacer eso.

Nota IMPORTANTE

El script usa xdotool's windowunmappara hacer invisible la ventana. El "cuadro" (icono) creado en su escritorio es la única "puerta" a la ventana oculta. En otras palabras: no elimine los archivos de escritorio manualmente. La ventana se perderá para siempre si lo haces.

Trabajo por hacer [editar 20-12: hecho ]

El script aún podría usar algo de refinamiento:

  • La geometría de la ventana no se restaura por definición. Se puede arreglar muy bien, pero pensé en mostrarte el primer resultado.
  • En la mayoría de los casos, la ventana en recuadro tiene su icono correcto. get_process(w_id)Sin embargo, la función podría usar alguna mejora. Si el proceso no se encuentra como un comando en /usr/share/applications, el archivo tiene un icono genérico.

Dar a los íconos de ventana en caja un tamaño diferente al de los otros íconos

El script nombra los .desktoparchivos creados siempre boxed_1.desktop , boxed_2.desktopetc., dependiendo del nombre "disponible" en el momento de la creación (nombres de archivo, no el nombre mostrado).

Puede cambiar el tamaño de los archivos (en general), haciendo clic con el botón derecho> tamaño del icono. La buena noticia es que si elimina el archivo y lo vuelve a crear, se recuerda el tamaño. Incluso si vuelve a crear el archivo después de reiniciar. Eso significa que si alguna vez cambiaste el tamaño de las ventanas en recuadro (p. Ej.) 1-5, siempre tendrán el mismo tamaño cuando (el script) las crees de nuevo.

ingrese la descripción de la imagen aquí

Jacob Vlijm
fuente
2
No puedo resistirme sin dejar un comentario, muy buena respuesta tuya :)
Ravan
¡Agradable! Pocos comentarios: 1. Reemplacé la línea dtop = "/home/jacob/Bureaublad"con una ruta a mi escritorio ( dtop = "/home/" + user + "/Desktop") 2. Restaurar haciendo doble clic no funcionó. Sospecho que source ~/.profileno es suficiente, iniciará / cerrará sesión rápidamente para probar esto. 3. En unit es posible cambiar el tamaño de los iconos manualmente (clic derecho -> cambiar el tamaño del icono), ¿es posible agregar algún parámetro f_contentpara establecer el tamaño del icono?
Artium
44
Cuando comencé a leer el primer párrafo de esta respuesta, ¡ sabía que habría un icono naranja en la parte inferior! ;-): P
Fabby
1
Hola @Artium, actualicé el script, ahora tiene algunas mejoras importantes, que incluyen una mejor búsqueda de íconos y restauración de geometría. ¡Diviértete!
Jacob Vlijm
1
@Artium Lo sé, pero prueba el que está en el script, es el ícono de carpeta habitual, similar a tu imagen. probablemente solo un enlace al mismo icono.
Jacob Vlijm
7

Puede usar fvwm para lograr esto.

  1. Instalar fvwm:

    sudo apt-get update
    sudo apt-get install fvwm
    
  2. Encuentre uno que use la función iconify: hay varios aquí: http://www.jmcunx.com/fvwm_theme.html Varios se parecen a la captura de pantalla que muestra.

  3. Copie el texto del tema, luego navegue hasta ~/.fvwm/(muestre primero los archivos ocultos) y luego cree un archivo.fvwm2rc

  4. Abra ese archivo en un editor de texto (como gedit) y pegue el texto del tema en él.

  5. Reinicie la computadora, seleccione fvwm e inicie sesión.

ingrese la descripción de la imagen aquí

Mateo
fuente