Nota
O script foi corrigido / corrigido em 16 de janeiro de 2017, corrigindo algumas aplicações das quais o 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 a disposição das janelas abaixo:
Paraler(lembre-se)dadisposiçãoatualdajanelaeseusaplicativos,executeoscriptcomaopção:
<script>-read
Emseguida,fechetodasasjanelas:
Então, para configurar o último arranjo de janela lembrado, execute-o com a opção:
<script> -run
e o último arranjo de janela lembrado será restaurado:
Issotambémfuncionaráapósareinicialização.
Colocandoosdoiscomandossobduasteclasdeatalhodiferentes,vocêpode"gravar" o arranjo da janela, desligar o computador e recuperar a mesma disposição da janela após (por exemplo) uma reinicialização.
O que o script faz e o que ele faz não
Execute com a opção -read
- O script usa
wmctrl
para listar todas as janelas, em todos os espaços de trabalho, suas posições, seus tamanhos, os aplicativos aos quais pertencem - O script "converte" as posições da janela de posições relativas (para a área de trabalho atual, como na saída de
wmctrl
) para absoluto , em seus espaços de trabalho de abrangência. Portanto, não importa se as janelas que você deseja lembrar estão em apenas uma área de trabalho ou espalhadas em diferentes áreas de trabalho. - O script "lembra" a organização da janela atual, gravando-a em um arquivo invisível no diretório inicial.
Execute com a opção -run
- o script lê o último arranjo de janela lembrado; inicia os aplicativos 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 bugs, alguns exemplos:
- as coordenadas da janela, como lidas por
wmctrl
, diferem levemente do comando para posicionar as janelas, como mencionado aqui . Portanto, as posições da janela recuperadas podem diferir ligeiramente da posição original. - Os comandos
wmctrl
funcionam um pouco imprevisíveis se a borda da janela estiver muito próxima doUnity Launcher
ou do painel. - As janelas "lembradas" precisam estar completamente dentro de uma borda da área de trabalho para que o comando
wmctrl
placement funcione bem.
Alguns aplicativos abrem novas janelas por padrão na mesma janela em uma nova guia (como gedit
). Eu consertei por gedit
, mas por favor mencione se você 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 em um arquivo vazio, salve-o como
recall_windows
in~/bin
. Crie o diretório, se necessário. Se o diretório ainda não existir, executesource ~/.profile
ou efetue logout / in após criar o diretório. Agora vai estar em$PATH
- Torne o script executável (!).
-
Agora abra algumas janelas,
gedit
,firefox
ou qualquer outra coisa, e teste-execute o script em um terminal executando o comando (nenhum prefixo de caminho é necessário):recall_windows -read
-
feche as janelas. Agora corra em um terminal:
recall_windows -run
A configuração da sua 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 botão "+" e adicione os comandos:
recall_windows -read
e
recall_windows -run
para duas teclas de atalho diferentes