Como posso fazer com que o wmctrl eleve a janela mais recentemente adotada de uma aplicação?

1

Eu tenho um script executando wmctrl -x -a "$1" . Ele traz a janela, passou como argumento para o roteiro, por exemplo:

wmctrl -x -a "Firefox" 

ativa o firefox.

No entanto, com aplicativos que possuem várias janelas, elas não abrem as últimas janelas usadas. Considere que eu tenho 3 janelas abertas em LibreOffice Writer , chamadas 'Doc 1', 'Doc 2' e 'Doc 3' e estou no Doc 3 e mudo para outro aplicativo. A execução do script traz o 'Doc 1' e não o 'Doc 3', que foi usado pela última vez.

Qualquer sinalizador para corrigir esse problema em wmctrl ?

    
por Salil Surendran 20.01.2017 / 23:06

1 resposta

2

A pedido, um splitoff de outra resposta, complementado com uma nova seção.

Histórico de foco das janelas

Como levantar a janela mais recentemente focada de uma aplicação

Como mencionado no meu comentário, atualmente, não há histórico de foco das janelas. Isso significa que, se precisarmos, precisamos criá-lo nós mesmos. O primeiro script abaixo faz exatamente isso; Ele monitora a janela atualmente focada e armazena o histórico em um arquivo minúsculo, atualizado uma vez por segundo. A ordem das linhas é também a ordem do foco; a linha superior representa a última janela focada, a última linha, a "mais antiga".

Para fazer um script levantar a janela focada mais recentemente de um aplicativo, tudo o que precisamos fazer é ler as linhas de cima para baixo, localizar a primeira ocorrência de uma janela do aplicativo e aumentá-la. Isso é exatamente o que o segundo script faz, se você executá-lo com o WM_CLASS da janela procurada.

Os scripts

  1. O script de plano de fundo, acompanhando o histórico de foco. Este script é uma cópia exata do primeiro aqui :

    #!/usr/bin/env python3
    import subprocess
    import time
    import os
    
    rootdata = os.environ["HOME"]+"/.focus_history"
    open(rootdata, "wt").write("This is an empty line")
    
    def current_windows():
        try:
            return subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
        except subprocess.CalledProcessError:
            pass
    
    def convert_format(w_id):
        return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]
    
    def read_data():
        return open(rootdata).read().splitlines()
    
    def get_top(wlist):
        try:
            top = convert_format(
                [l.split("#")[-1].strip() for l in subprocess.check_output(
                    ["xprop", "-root"]
                    ).decode("utf-8").splitlines() \
                   if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0])
            return [l for l in wlist if top in l][0]
        except IndexError:
            pass
    
    if __name__ == "__main__":
        while True:
            time.sleep(1)
            wdata = current_windows()
            if wdata != None:
                wlist = wdata.splitlines()
                # get frontmost window (as in wmctrl -lG)
                top = get_top(wlist)
                oldlist = read_data()
                if not any([top == oldlist[0], top == None]):
                    # clean up closed windows
                    [oldlist.remove(l) for l in oldlist if not l.split()[0] in wdata]
                    # remove possible other mentions of the active window
                    [oldlist.remove(l) for l in oldlist if l.startswith(top.split()[0])]
                    open(rootdata, "wt").write(("\n").join([top]+oldlist))
    

    Copie o script em um arquivo vazio, salve-o como focus_history.py

  2. O script para levantar a última janela focada de um aplicativo.

    #!/usr/bin/env python3
    import os
    import subprocess
    import sys
    
    lookfor = sys.argv[1]
    winhistory = os.environ["HOME"]+"/.focus_history"
    
    for l in open(winhistory):
        wid = l.split()[0]
        wmclass = subprocess.check_output(
            ["xprop", "-id", wid, "WM_CLASS"]
            ).decode("utf-8").strip()
        if lookfor in wmclass:
            subprocess.check_output(["wmctrl", "-ia", wid])
            break
    

    Salve como raise_recent.py .

Como usar

  1. verifique se wmctrl está instalado:

    sudo apt install wmctrl
    
  2. Teste- execute o primeiro script como um backgrounder com o comando:

    python3 /path/to/focus_history.py
    

    NB certifique-se de que o script inicie antes de outras janelas abertas, senão as janelas só serão gravadas (claro) assim que receberem o seu primeiro foco.

  3. Chame o segundo script com o comando (por exemplo,

    python3 /path/to/raise_recent.py gedit
    

    ... para levantar a janela mais recentemente focada de gedit .

  4. Se tudo funcionar bem, adicione o primeiro script a Startup Applications. Observe, no entanto, que você provavelmente precisará adicionar uma quebra antes de iniciar o script, para evitar que wmctrl seja interrompido. (Embora o script não deva, uma vez que lida com a possível exceção).

É isso aí.

    
por Jacob Vlijm 29.10.2017 / 10:39