Remarque
Le script a été corrigé / corrigé le 16 janvier 2017, corrigeant certaines applications dont le nom du processus diffère de la commande pour exécuter l'application . Cela peut se produire occasionnellement sur les applications. Si quelqu'un en trouve un, veuillez laisser un commentaire.
Script pour mémoriser et restaurer l'agencement des fenêtres et leurs applications correspondantes.
Le script ci-dessous peut être exécuté avec deux options. Disons que vous avez l'agencement des fenêtres comme ci-dessous:
Pour lire (mémoriser) l'agencement actuel des fenêtres et leurs applications, exécutez le script avec l'option:
<script> -read
Fermez ensuite toutes les fenêtres:
Ensuite, pour configurer la dernière disposition de fenêtre mémorisée, exécutez-la avec l'option:
<script> -run
et la dernière disposition de fenêtre mémorisée sera restaurée:
Cela fonctionnera également après un redémarrage.
En plaçant les deux commandes sous deux touches de raccourci différentes, vous pouvez «enregistrer» votre disposition de fenêtres, arrêter votre ordinateur et rappeler la même disposition de fenêtres après (par exemple) un redémarrage.
Ce que fait le script et ce qu'il ne fait pas
Exécuter avec l'option -read
- Le script utilise
wmctrl
pour répertorier toutes les fenêtres, dans tous les espaces de travail, leurs positions, leurs tailles, les applications auxquelles elles appartiennent
- Le script «convertit» ensuite les positions de la fenêtre de positions relatives (dans l'espace de travail actuel, comme dans la sortie de
wmctrl
) en positions absolues , sur vos espaces de travail étendus. Par conséquent, peu importe si les fenêtres dont vous souhaitez vous souvenir se trouvent sur un seul espace de travail ou se répartissent sur différents espaces de travail.
- Le script "se souvient" alors de la disposition actuelle de la fenêtre, l'écrivant dans un fichier invisible dans votre répertoire personnel.
Exécuter avec l'option -run
- le script lit la dernière disposition de fenêtre mémorisée; il démarre les applications correspondantes, déplace les fenêtres vers les positions mémorisées, également à l'aide de
wmctrl
Le script ne se souvient pas des fichiers qui pourraient éventuellement être ouverts dans les fenêtres, ni (par exemple) des sites Web qui ont été ouverts dans une fenêtre de navigateur.
Problèmes
La combinaison de wmctrl
et Unity
a quelques bugs, quelques exemples:
- les coordonnées de la fenêtre, telles que lues par,
wmctrl
diffèrent légèrement de la commande de positionnement des fenêtres, comme mentionné ici . Par conséquent, les positions de fenêtre rappelées peuvent légèrement différer de la position d'origine.
- Les
wmctrl
commandes fonctionnent un peu imprévisibles si le bord de la fenêtre est très proche du Unity Launcher
ou du panneau.
- Les fenêtres "mémorisées" doivent être complètement à l'intérieur des bordures d'un espace de travail pour que la
wmctrl
commande de placement fonctionne correctement.
Certaines applications ouvrent de nouvelles fenêtres par défaut dans la même fenêtre dans un nouvel onglet (comme gedit
). Je l'ai corrigé pour gedit
, mais veuillez le mentionner si vous trouvez plus d'exceptions.
Le 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()
Comment installer
Avant de commencer, assurez-vous qu'il wmctrl
est installé:
sudo apt-get install wmctrl
Ensuite:
- Copiez le script dans un fichier vide, enregistrer comme
recall_windows
dans ~/bin
. Créez le répertoire si nécessaire. Si le répertoire n'existait pas encore, exécutez l'un source ~/.profile
ou l' autre ou déconnectez-vous / après avoir créé le répertoire. Ce sera désormais$PATH
- Rendez le script exécutable (!).
Maintenant , ouvrez quelques fenêtres, gedit
, firefox
ou autre, et exécuter le script de test dans un terminal en exécutant la commande (pas de préfixe de chemin nécessaire):
recall_windows -read
fermer les fenêtres. Maintenant, exécutez dans un terminal:
recall_windows -run
La configuration de votre fenêtre devrait maintenant être restaurée
Si tout fonctionne correctement, ajoutez deux commandes aux touches de raccourci: Choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez les commandes:
recall_windows -read
et
recall_windows -run
à deux touches de raccourci différentes