Nota
Lo script è stato corretto / corretto il 16 gennaio 2017, risolvendo alcune applicazioni per le quali il nome del processo differisce dal comando per eseguire l'applicazione . È possibile che ciò si verifichi occasionalmente nelle applicazioni. Se qualcuno lo trova, ti preghiamo di lasciare un commento.
Script per ricordare e ripristinare la disposizione delle finestre e le relative applicazioni.
Lo script seguente può essere eseguito con due opzioni. Diciamo che hai la disposizione della finestra come di seguito:
Per leggere (ricordare) l'attuale disposizione delle finestre e le loro applicazioni, eseguire lo script con l'opzione:
<script> -read
Quindi chiudere tutte le finestre:
Quindi, per impostare l'ultima disposizione della finestra ricordata, eseguirla con l'opzione:
<script> -run
e verrà ripristinata l'ultima disposizione della finestra ricordata:
Funzionerà anche dopo un riavvio.
Mettendo i due comandi in due diversi tasti di scelta rapida, è possibile "registrare" la disposizione della finestra, spegnere il computer e richiamare la stessa disposizione della finestra dopo (ad esempio) un riavvio.
Cosa fa lo script e cosa no
Esegui con l'opzione -read
- Lo script utilizza
wmctrl
per elencare tutte le finestre, tutte le aree di lavoro, le loro posizioni, le loro dimensioni, le applicazioni a cui appartengono
- Lo script quindi "converte" le posizioni della finestra da relative (allo spazio di lavoro corrente, come nell'output di
wmctrl
) a posizioni assolute , sulle aree di lavoro di spanning. Pertanto, non importa se le finestre che si desidera ricordare si trovano su una sola area di lavoro o si estendono su aree di lavoro diverse.
- Lo script quindi "ricorda" l'attuale disposizione della finestra, scrivendola in un file invisibile nella tua home directory.
Esegui con l'opzione -run
- la sceneggiatura legge l'ultima disposizione della finestra ricordata; avvia le applicazioni corrispondenti, sposta le finestre nelle posizioni memorizzate, anche con l'aiuto di
wmctrl
Lo script non ricorda i file che potrebbero essere aperti nelle finestre, né (ad esempio) i siti Web che sono stati aperti in una finestra del browser.
Problemi
La combinazione di wmctrl
e Unity
ha alcuni bug, alcuni esempi:
- le coordinate della finestra, come lette da
wmctrl
differiscono leggermente formano il comando per posizionare le finestre, come indicato qui . Pertanto, le posizioni della finestra richiamate potrebbero differire leggermente dalla posizione originale.
- I
wmctrl
comandi funzionano un po 'imprevedibili se il bordo della finestra è molto vicino Unity Launcher
al pannello o.
- Le finestre "ricordate" devono essere completamente all'interno dei bordi di uno spazio di lavoro affinché il
wmctrl
comando di posizionamento funzioni correttamente.
Alcune applicazioni aprono nuove finestre per impostazione predefinita nella stessa finestra in una nuova scheda (come gedit
). L'ho risolto per gedit
, ma per favore, menzionalo se trovi altre eccezioni.
Il copione
#!/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()
Come impostare
Prima di iniziare, assicurati che wmctrl
sia installato:
sudo apt-get install wmctrl
Poi:
- Copia lo script in un file vuoto, salvalo come
recall_windows
in ~/bin
. Creare la directory se necessario. Se la directory non esiste ancora, esegui source ~/.profile
o disconnetti / accedi dopo aver creato la directory. Ora sarà dentro$PATH
- Rendi eseguibile lo script (!).
Ora aprire un paio di finestre, gedit
, firefox
o qualsiasi altra cosa, e test-eseguire lo script in un terminale eseguendo il comando (senza prefisso del percorso necessario):
recall_windows -read
chiudi le finestre. Ora corri in un terminale:
recall_windows -run
L'impostazione della finestra dovrebbe ora essere ripristinata
Se tutto funziona correttamente, aggiungi due comandi ai tasti di scelta rapida: Scegli: Impostazioni di sistema> "Tastiera"> "Scorciatoie"> "Scorciatoie personalizzate". Fai clic su "+" e aggiungi i comandi:
recall_windows -read
e
recall_windows -run
a due diversi tasti di scelta rapida