Nota
O script foi corrigido / corrigido em 16 de janeiro de 2017, corrigindo alguns aplicativos cujo nome do processo difere do comando para executar o aplicativo . Possivelmente, isso ocorre ocasionalmente em aplicativos. Se alguém encontrar um, por favor deixe um comentário.
Script para lembrar e restaurar o arranjo da janela e seus aplicativos correspondentes.
O script abaixo pode ser executado com duas opções. Digamos que você tenha o arranjo de janelas como abaixo:
Para ler (lembrar) a organização atual da janela e seus aplicativos, execute o script com a opção:
<script> -read
Depois feche todas as janelas:
Em seguida, para configurar o último arranjo de janelas lembrado, execute-o com a opção:
<script> -run
e o último arranjo da janela lembrado será restaurado:
Isso também funcionará após uma reinicialização.
Colocando os dois comandos sob duas teclas de atalho diferentes, você pode "gravar" o arranjo da janela, desligar o computador e recuperar o mesmo arranjo da janela após (por exemplo) uma reinicialização.
O que o script faz e o que não faz
Corra com a opção -read
- O script usa
wmctrl
para listar todas as janelas, em todos os espaços de trabalho, suas posições, tamanhos, aplicativos a que pertencem
- O script "converte" as posições da janela de relativas (para o espaço de trabalho atual, como na saída de
wmctrl
) para posições absolutas , nos seus espaços de trabalho de abrangência. Portanto, não importa se as janelas que você deseja lembrar estão em apenas um espaço de trabalho ou se espalham por diferentes espaços de trabalho.
- O script "lembra" o arranjo atual da janela, gravando-o em um arquivo invisível no diretório inicial.
Corra com a opção -run
- o script lê o último arranjo de janelas lembrado; inicia as aplicações correspondentes, move as janelas para as posições lembradas, também com a ajuda de
wmctrl
O script não lembra os arquivos que possivelmente podem ser abertos nas janelas, nem (por exemplo) os sites que foram abertos em uma janela do navegador.
Problemas
A combinação de wmctrl
e Unity
tem alguns erros, alguns exemplos:
- as coordenadas da janela, conforme lidas por,
wmctrl
diferem ligeiramente do comando para posicionar as janelas, conforme mencionado aqui . Portanto, as posições recuperadas da janela podem diferir ligeiramente da posição original.
- Os
wmctrl
comandos funcionam um pouco imprevisíveis se a borda da janela estiver muito próxima Unity Launcher
ao painel ou.
- As janelas "lembradas" precisam estar completamente dentro das bordas de uma área de trabalho para que o
wmctrl
comando de posicionamento funcione bem.
Alguns aplicativos abrem novas janelas por padrão na mesma janela em uma nova guia (como gedit
). Eu o corrigi gedit
, mas mencione se encontrar mais exceções.
O script
#!/usr/bin/env python3
import subprocess
import os
import sys
import time
wfile = os.environ["HOME"]+"/.windowlist"
arg = sys.argv[1]
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def check_window(w_id):
w_type = get("xprop -id "+w_id)
if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
return True
else:
return False
def get_res():
# get resolution and the workspace correction (vector)
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
res = [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
vp_data = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
curr_vpdata = [int(n) for n in vp_data[5].split(",")]
return [res, curr_vpdata]
app = lambda pid: subprocess.check_output(["ps", "-p", pid, "-o", "comm="]).decode("utf-8").strip()
def read_windows():
res = get_res()
w_list = [l.split() for l in get("wmctrl -lpG").splitlines()]
relevant = [[w[2],[int(n) for n in w[3:7]]] for w in w_list if check_window(w[0]) == True]
for i, r in enumerate(relevant):
relevant[i] = app(r[0])+" "+str((" ").join([str(n) for n in r[1]]))
with open(wfile, "wt") as out:
for l in relevant:
out.write(l+"\n")
def open_appwindow(app, x, y, w, h):
ws1 = get("wmctrl -lp"); t = 0
# fix command for certain apps that open in new tab by default
if app == "gedit":
option = " --new-window"
else:
option = ""
# fix command if process name and command to run are different
if "gnome-terminal" in app:
app = "gnome-terminal"
elif "chrome" in app:
app = "/usr/bin/google-chrome-stable"
subprocess.Popen(["/bin/bash", "-c", app+option])
# fix exception for Chrome (command = google-chrome-stable, but processname = chrome)
app = "chrome" if "chrome" in app else app
while t < 30:
ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
if app in p and w[2] in p] for w in ws2]
if len(procs) > 0:
time.sleep(0.5)
w_id = procs[0][0][1]
cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+procs[0][0][1]+" -e 0,"+x+","+y+","+w+","+h
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
def run_remembered():
res = get_res()[1]
try:
lines = [l.split() for l in open(wfile).read().splitlines()]
for l in lines:
l[1] = str(int(l[1]) - res[0]); l[2] = str(int(l[2]) - res[1] - 24)
open_appwindow(l[0], l[1], l[2], l[3], l[4])
except FileNotFoundError:
pass
if arg == "-run":
run_remembered()
elif arg == "-read":
read_windows()
Como configurar
Antes de começar, verifique se wmctrl
está instalado:
sudo apt-get install wmctrl
Então:
- Copie o script para um arquivo vazio, salve-o como
recall_windows
em ~/bin
. Crie o diretório, se necessário. Se o diretório ainda não existir, execute source ~/.profile
ou efetue logout / logon depois de criar o diretório. Agora estará em$PATH
- Torne o script executável (!).
Agora abra algumas janelas, gedit
, firefox
ou o que quer, e teste-executar o script em um terminal executando o comando (nenhum caminho prefixo necessário):
recall_windows -read
feche as janelas. Agora execute em um terminal:
recall_windows -run
Sua configuração de janela agora deve ser restaurada
Se tudo funcionar bem, adicione dois comandos às teclas de atalho: Escolha: Configurações do sistema> "Teclado"> "Atalhos"> "Atalhos personalizados". Clique no "+" e adicione os comandos:
recall_windows -read
e
recall_windows -run
para duas teclas de atalho diferentes