Posso minimizar uma janela em uma caixa no Unity?

17

No 4Dwm da Irix, havia a capacidade de minimizar janelas em uma caixa (ao contrário da barra de tarefas usada pelos modernos gerenciadores de janelas). Eu vi isso também em um antigo HPUX.

Veja o quadrado "console" na imagem vinculada:

É possível realizar no Ubuntu, seja com um plugin ou talvez com algum gerenciador de janelas diferente do Unity?

    
por Artium 18.12.2015 / 16:13

2 respostas

18

Para minha própria surpresa, funciona muito bem, contanto que você não tenha muitas outras coisas na sua área de trabalho .

Eu trabalhei com isso por um tempo, e parece uma alternativa estranha, mas estranhamente legal para frequentar switches do espaço de trabalho. Refrescante por sua simplicidade.

Na prática

A solução é basicamente o que você descreve:

  • Pressionar uma combinação de teclas "marcará" a janela da sua área de trabalho, em uma janela:

    emumícone,comaaparênciadoaplicativo:

  • Cliqueduasvezesnoíconeeajanelaseráexibidanovamenteeoíconedesaparecerá.

Comofunciona

Oconto(explicação):

  • Aopressionaratecladeatalho,oscriptéchamadocomoargumentobox:

    windowboxbox
  • Oscriptentão:

    • lêoiddajaneladaprimeirajanela
    • verificaseéumajanela"normal" (você não desejaria desmapear sua área de trabalho, por exemplo)
    • pesquisa o nome do processo do aplicativo, possuindo a janela.
    • pesquisa o ícone correspondente no arquivo .desktop do aplicativo correspondente em /usr/share/applications
    • cria um arquivo .desktop com o nome exclusivo, com uma linha Exec= que chama o script (quando clicado duas vezes) com o argumento show :

      windowbox show
      

O arquivo .desktop adicionará vários argumentos de argumentos adicionais, como o id da janela, o nome (arquivo) do arquivo .desktop .

Posteriormente:

  • O arquivo .desktop é então executado como executável, para torná-lo um objeto que pode ser clicado duas vezes.

  • Quando o arquivo .desktop é clicado duas vezes, a janela é (re) mapeada, o arquivo .desktop é removido da sua área de trabalho.

Como configurar

  1. Como praticamente sempre, quando você quer brincar com o Windows, o script precisa de ambos wmctrl e xdotool :

    sudo apt-get install xdotool wmctrl
    
  2. Crie o diretório ~/bin ( ~ significa seu diretório inicial)
  3. Copie o script abaixo em um arquivo vazio, salve-o como windowbox (sem extensão) em ~/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. Torne o script executável

  5. Para tornar o diretório recém-criado "pop-up" em $PATH , efetue logout / in ou execute source ~/.profile (a partir de uma janela de terminal)
  6. Teste- execute o script a partir de uma janela de terminal pelo comando:

    windowbox box
    

    A janela deve desaparecer, a janela "boxed" deve aparecer na sua área de trabalho.

  7. Se tudo funcionar bem, adicione o seguinte comando a uma tecla de atalho: escolha o ícone de roda dentada no canto superior direito da tela:

  8. VáparaConfiguraçõesdoSistemaTecladoAtalhosAtalhosPersonalizados.Cliqueno+eadicioneocomando:

    windowboxbox

Issodeveserfeito.

Notaimportante

Oscriptusaxdotoolwindowunmapparatornarajanelainvisível.A"caixa" criada (ícone) na sua área de trabalho é o único "portão" para a janela oculta. Em outras palavras: não remova o (s) arquivo (s) da área de trabalho manualmente. A janela será perdida definitivamente se você fizer isso.

Trabalho a fazer [editar 20-12: feito ]

O script ainda poderia usar algum refinamento:

  • A geometria da janela não é restaurada por definição. Pode ser consertado muito bem, mas eu pensei em te mostrar o primeiro resultado.
  • Na maioria dos casos, a janela na caixa tem seu ícone correto. A função get_process(w_id) poderia, no entanto, melhorar. Se o processo não for encontrado como um comando em /usr/share/applications , o arquivo terá um ícone genérico.

Dar aos ícones de janelas com caixas um tamanho diferente dos outros ícones

O script nomeia os arquivos .desktop criados sempre boxed_1.desktop , boxed_2.desktop etc, dependendo do nome "disponível" no momento da criação (nomes de arquivos, não o nome exibido).

Você pode redimensionar os arquivos (em geral), clicando com o botão direito > tamanho do ícone. A boa notícia é que, se você remover o arquivo e recriá-lo, o tamanho será lembrado. Mesmo se você criar o arquivo novamente após uma reinicialização. Isso significa que se você redimensionou as janelas em caixa (por exemplo, 1-5), elas sempre terão o mesmo tamanho quando você (o script) as criar novamente ! p>

    
por Jacob Vlijm 19.12.2015 / 12:45
7

Você pode usar o fvwm para realizar isso.

  1. Instalar o fvwm:

    sudo apt-get update
    sudo apt-get install fvwm
    
  2. Encontre um grupo que use a função iconify - há vários aqui: link Vários parecem com a tela -tudo que você mostra.

  3. Copie o texto do tema e navegue até ~/.fvwm/ (primeiro, mostre os arquivos ocultos) e, em seguida, crie um arquivo .fvwm2rc

  4. Abra esse arquivo em um editor de texto (como o gedit) e cole o texto do tema nele.

  5. Reinicie o computador e selecione fvwm e login.

    
por Mateo 21.12.2015 / 00:36