17 votos

¿Puedo minimizar una ventana en una caja en Unity?

En el 4Dwm de Irix, existía la posibilidad de minimizar Windows en un recuadro (al contrario que la barra de tareas utilizada por los gestores de ventanas modernos). He visto esto también en un viejo HPUX.

Véase el cuadrado de la "consola" en la imagen enlazada:

enter image description here

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

0 votos

Pregunta rara, pero interesante :) Se me ocurre algo así. ¿Importaría el icono o podría ser uno genérico? ¿Cómo se comporta? como un icono en el escritorio o una "ventana" mínima.

0 votos

@JacobVlijm El icono no es genérico. Cada aplicación tiene su propio icono como los iconos de Windows minimizados en Unity)

0 votos

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 intentarlo? (sería un trabajo interesante, pero desafiante, mejor preguntar antes de empezar :) )

18voto

Jacob Vlijm Puntos 24137

Para mi propia sorpresa, funciona bastante bien, Siempre y cuando no tengas demasiadas otras cosas en tu escritorio. .

Trabajé con él durante un tiempo, y parece un extraño, pero extrañamente bonito alternativa a los frecuentes cambios de espacio de trabajo. Refrescante por su sencillez.

En la práctica

En realidad, la solución es más o menos la que describes:

  • Al pulsar una combinación de teclas, la ventana se "encajona" en el escritorio, desde una ventana:

    enter image description here

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

    enter image description here

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

Cómo funciona

La historia corta (explicación):

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

    windowbox box
  • El script entonces:

    • lee el identificador de la ventana situada más al frente
    • comprueba si se trata de una ventana "normal" (por ejemplo, no querrás desmapear tu escritorio)
    • Busca el nombre del proceso de la aplicación, propietario de la ventana.
    • Busca el icono correspondiente en la aplicación correspondiente de .desktop archivo en /usr/share/applications
    • crea un nombre único .desktop con un Exec= que llama al script (cuando se hace doble clic) con el argumento show :

      windowbox show

En .desktop añadirá una serie de argumentos adicionales, como el id de la ventana, el nombre (de archivo) del .desktop archivo.

Posteriormente:

  • En .desktop para convertirlo en un objeto sobre el que se puede hacer doble clic.

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

Cómo instalarlo

  1. Como prácticamente siempre, cuando se quiere jugar con Windows, el script necesita tanto wmctrl y xdotool :

    sudo apt-get install xdotool wmctrl
  2. Crear el directorio ~/bin ( ~ representa su directorio personal)

  3. Copie el script siguiente 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 ejecutable el script

  5. Para que el directorio recién creado "aparezca" en $PATH cierre la sesión o ejecute source ~/.profile (desde una ventana de terminal)

  6. Prueba- ejecuta el script desde una ventana de terminal mediante el comando:

    windowbox box

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

  7. Si todo funciona bien, añade el siguiente comando a una tecla de acceso directo: elige el icono del engranaje en la parte superior derecha de tu pantalla:

    Gear icon

  8. Ir a System SettingsKeyboardShortcutsCustom Shortcuts . Haga clic en el botón + y añade el comando:

    windowbox box

Con eso debería bastar.

Nota importante

El script utiliza xdotool 's windowunmap para hacer invisible la ventana. La "caja" (icono) creada en tu escritorio es la única "puerta" a la ventana oculta. En otras palabras: no elimines el/los archivo(s) del escritorio manualmente. La ventana se perderá para siempre si lo haces.

Trabajo por hacer [editar 20-12: hecho ]

El script aún podría perfeccionarse:

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

Dar a los iconos de las ventanas en recuadro un tamaño diferente al de los demás iconos.

El script nombra a los creados .desktop archivos siempre boxed_1.desktop , boxed_2.desktop etc., en función del nombre "disponible" en el momento de la creación (nombres de archivo, no el nombre visualizado).

Puedes cambiar el tamaño de los archivos (en general), haciendo clic con el botón derecho del ratón > tamaño del icono. La buena noticia es que si eliminas el archivo y lo vuelves a crear, el tamaño se recuerda. Incluso si creas el archivo de nuevo después de un reinicio. Esto significa que si ever redimensionado el cuadro de Windows (por ejemplo) 1-5, se siempre ¡tengan el mismo tamaño cuando usted (el script) los cree de nuevo!

enter image description here

2 votos

No puedo resistirme sin dejar un comentario, muy buena respuesta por tu parte :)

0 votos

¡Que bien! Algunos comentarios: 1. He sustituido 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 ~/.profile no es suficiente se conectará/desconectará rápidamente para probarlo. 3. En unity es posible redimensionar los iconos manualmente (click derecho -> redimensionar icono), ¿es posible añadir algún parámetro en f_content ¿para fijar el tamaño del icono?

0 votos

@Artium aaaarrrrggggh, mi(s) punto(s) ciego(s), 1. mientras trabajaba, pensé que no debía olvidar la ruta a tu Escritorio, pero lo hice... 2. puedes averiguarlo ejecutando desde una terminal. 3. buena sugerencia, no estoy seguro de si se puede cambiar el tamaño de un solo icono.

7voto

Cyberbear Puntos 11

Puede utilizar fvwm para lograrlo.

  1. Instala fvwm:

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

  3. Copie el texto del tema y, a continuación, vaya a ~/.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 en él el texto del tema.

  5. Reinicie el ordenador y seleccione fvwm e inicie sesión.

enter image description here

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X