Je fais l'essentiel de mon travail dans deux applications: mon navigateur web et mon éditeur. Je passe fréquemment de l'un à l'autre avec Alt-Tab. J'ai également un client de messagerie instantanée (Hipchat) ouvert à tout moment, mais je n'interagis avec lui que rarement par rapport aux deux autres applications.
Une gêne récurrente est qu'après avoir interagi avec la fenêtre Hipchat et Alt-Tab vers (par exemple) mon éditeur, ma mémoire musculaire est réglée pour s'attendre à ce qu'un autre Alt-Tab se concentre sur mon navigateur, mais je me retrouve à nouveau sur Hipchat.
Existe-t-il un moyen de faire en sorte que Hipchat soit envoyé au bas de la pile ou de la liste de récence ou quoi que ce soit, après avoir perdu le focus par quelque moyen que ce soit?
Ce que vous demandez, c'est d'autoriser la fenêtre d'une application spécifique à seulement apparaître soit en première ou en dernière position, z -sage.
Lorsque la fenêtre gedit (dans cet exemple) perd le focus, elle est envoyée à la dernière position (dans le sens z, en dessous de la fenêtre de terminal semi-transparente) au lieu de descendre d'une seule position:
Bien que cela puisse être fait, nous devons encore surmonter de graves complications; Lorsque la fenêtre est envoyée à la toute dernière position, vous souhaiterez conserver l'ordre z de toutes les autres fenêtres. Cependant, actuellement, aucun outil ne peut nous donner cet ordre z de fenêtres. xdotool
et wmctrl
ne nous fournissent aucune information à ce sujet.
Ce que nous pouvons faire, cependant, est de garder une trace de l'historique de mise au point de (toutes) les fenêtres. Puisqu'une fenêtre descend d'une position si une autre fenêtre obtient le focus, nous pouvons conclure l'ordre z des fenêtres si nous exécutons un script d'arrière-plan pour regarder l'historique du focus des fenêtres.
La solution ci-dessous existe de deux petits scripts d'arrière-plan, à exécuter simultanément.
focus_history.py
set_z.py
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 __== "__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))
#!/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
Le script utilise à la fois wmctrl
et xdotool
Sudo apt-get install wmctrl xdotool
Copiez le script 1 dans un fichier vide, enregistrez-le (exactement!) Sous focus_history.py
Copiez le script 2 dans un fichier vide, enregistrez-le sous set_z.py
dans le même répertoire exact que le script 1.
Dans la section head du script, dans la ligne:
proc = "gedit"
remplacer "gedit"
par le nom du processus de votre application (entre guillemets)
Testez- exécutez le script: Avant d'ouvrir des fenêtres (supplémentaires), lancez le script 1 par la commande:
python3 /path/to/focus_history.py & python3 /path/to/set_z.py
[Le script reconnaîtra les fenêtres qui ont été focalisées au moins une fois. Ce sera le cas si le script est exécuté lors de la connexion]
Comme mentionné, les scripts doivent être dans un seul et même répertoire, au même niveau.
Maintenant, commencez à ouvrir les fenêtres et voyez comment cela se comporte. Votre application doit passer à l'arrière-plan (très) si elle perd le focus.
Si tout fonctionne bien, ajoutez-le aux applications de démarrage: Dash> Applications de démarrage> Ajouter. Ajoutez la commande:
/bin/bash -c "sleep 15 && python3 /path/to/focus_history.py & python3 /path/to/set_z.py"
Alternativement, vous pouvez définir une touche de raccourci pour ouvrir la fenêtre d'une application spécifique si elle existe, comme expliqué ici .
Cela nécessiterait cependant d'avoir un autre raccourci pour revenir à la fenêtre de la première application,
À moins que ...,
Vous devez configurer un raccourci pour basculer entre deux applications. Cela serait cependant hors de portée de cette question ...