Posso enviar automaticamente a janela de uma aplicação em particular para a posição z mais baixa, quando perde o foco?

3

Eu faço a maior parte do meu trabalho em dois aplicativos: meu navegador da web e meu editor. Alterno entre eles frequentemente com o Alt-Tab. Eu também tenho um cliente de mensagens instantâneas (Hipchat) aberto em todos os momentos, mas eu interajo com ele apenas raramente em comparação com os outros dois aplicativos.

Um incômodo recorrente é que depois que eu interajo com a janela do Hipchat e o Alt-Tab de volta para (digamos) meu editor, minha memória muscular está ajustada para esperar que outro Alt-Tab se concentre no meu navegador, mas acabo no Hipchat novamente.

Existe alguma maneira de fazer com que o Hipchat seja enviado para o final da pilha ou lista de recência ou o que quer que seja, depois de perder o foco por qualquer meio?

    
por Sean 10.03.2016 / 23:32

1 resposta

3

O que você está perguntando é permitir que a janela de um aplicativo específico somente apareça na primeira ou na última posição, z-wise.

Quando a janela do gedit (neste exemplo) perde o foco, ela é enviada para a última poição (z-wise, abaixo da janela do terminal semitransparente) em vez de descer apenas uma posição :

Z-posiçãodeumajanela

Emboraissopossaserfeito,aindaprecisamossuperaralgumascomplicaçõessérias;Quandoajanelaéenviadaparaaúltimaposição,vocêdevemanteraordemzdetodasasoutrasjanelas.Noentanto,atualmente,nãoháferramentasquepossamnosdaressaordemzdejanelas.Tantoxdotoolquantowmctrlnãonosdãonenhumainformaçãosobreisso.

Oquepodemosfazer,noentanto,éacompanharohistóricodefocodetodasasjanelas.Comoumajaneladesceumaposiçãoseoutrajanelativerfoco,podemosconcluiraordemzdasjanelasseexecutarmosumscriptdesegundoplanoparaobservarohistóricodefocodasjanelas.

Asoluçãodoispequenosscriptsdesegundoplano

Asoluçãoabaixoexistededoispequenosscriptsdesegundoplano,paraseremexecutadossimultaneamente.

  1. Umscriptparaacompanharohistóricodefoco:focus_history.py
  2. Umscriptparaenviarajaneladoaplicativodedestinoparaaúltimaposiçãoseperderofoco:set_z.py

Script1

focus-history.py

#!/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))

Script 2

#!/usr/bin/python3
import subprocess
import time
import focus_history

# --- set the process name of your application below
proc = "gedit"
# ---

focus_hist = focus_history.rootdata

def get(val):
    try:
        return subprocess.check_output(val).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

def front_w():
    get_front = str(hex(int(get(["xdotool", "getactivewindow"]))))
    return get_front[:2]+(10-len(get_front))*"0"+get_front[2:]

while True:
    time.sleep(1)
    pid = get(["pgrep", proc])
    front1 = ""
    while pid:
        time.sleep(1)
        frontpid = get(["xdotool", "getactivewindow", "getwindowpid"])
        front2 = frontpid == pid
        if front2 != front1:
            if front2 == False:
                zdata = [l for l in open(focus_hist).read().splitlines()]
                wins = list(reversed([l.split()[0] for l in zdata if not pid in l]))
                for w in wins+[front_w()]:
                    cmd = ["xdotool", "windowraise", w]
                    subprocess.call(cmd)
        pid = get(["pgrep", proc])            
        front1 = front2

Como configurar

  1. O script usa wmctrl e xdotool

    sudo apt-get install wmctrl xdotool
    
  2. Copie o script 1 em um arquivo vazio, salve-o (exatamente!) como focus_history.py

  3. Copie o script 2 em um arquivo vazio, salve-o como set_z.py no mesmo diretório do script 1.

    Na seção principal do script, na linha:

    proc = "gedit"
    

    substitua "gedit" pelo nome do processo do seu aplicativo (entre aspas)

  4. Teste- execute o script: Antes de abrir qualquer janela (adicional) , inicie o script 1 pelo comando:

    python3 /path/to/focus_history.py & python3 /path/to/set_z.py
    

    [O script reconhecerá as janelas que foram focadas pelo menos uma vez. Esse será o caso se o script for executado no log in]

    Como mencionado, os scripts devem estar em um único diretório, no mesmo nível.

  5. Agora comece a abrir as janelas e veja como elas se comportam. Seu aplicativo deve passar para o (muito) plano de fundo se perder o foco.

  6. Se tudo funcionar bem, adicione-o aos aplicativos de inicialização: Dash > Aplicativos de inicialização > Adicionar. Adicione o comando:

    /bin/bash -c "sleep 15 && python3 /path/to/focus_history.py & python3 /path/to/set_z.py"
    

Notas

  • a configuração pressupõe que você tenha uma janela única aberta no aplicativo de destino. De sua pergunta, eu entendo que é o caso.

Alternativamente

Como alternativa, você pode definir uma tecla de atalho para levantar a janela de um aplicativo específico, se existir, conforme explicado aqui .

Isso exigiria, no entanto, outro atalho para voltar à janela do primeiro aplicativo,

A menos que ...

Você configuraria um atalho para alternar entre dois aplicativos. Isso, no entanto, estaria fora do escopo desta questão ...

    
por Jacob Vlijm 14.03.2016 / 13:54