Я делаю большую часть своей работы в двух приложениях: мой веб-браузер и мой редактор. Я часто переключаюсь назад и вперед между ними с Alt-Tab. У меня также есть клиент IM (Hipchat), открытый в любом случае, но я взаимодействую с ним только редко по сравнению с другими двумя приложениями.
Повторяющееся раздражение - то, что после того, как я взаимодействую с окном Hipchat и Alt-Tab назад, чтобы (сказать) моего редактора, моя память мышц настраивается, чтобы ожидать, что другой Alt-Tab сфокусируется на моем браузере, но я заканчиваю на Hipchat снова.
Там какой-либо путь состоит в том, чтобы заставить Hipchat быть отправленным в дно стека или списка новизны или независимо от того, что это, после того, как это теряет фокус каким-либо образом?
То, что Вы спрашиваете, должно на самом деле позволить окну определенного приложения только появляться или на первом - или на последней позиции, z-wise.
Когда gedit окно (в этом примере) теряет фокус, это отправляется в последний poition (z-wise ниже полупрозрачного окна терминала) вместо того, чтобы убывать только одно положение:
В то время как это может быть сделано, мы все еще должны преодолеть некоторые серьезные сложности; Когда окно будет отправлено в самое последнее положение, Вы захотите сохранить z-порядок всех других окон. Однако в настоящее время нет никаких инструментов, которые могут дать нам этот z-порядок окон. Оба xdotool
и wmctrl
не дайте нам информацию об этом вообще.
Что мы можем сделать, однако должен отслеживать историю фокуса (всех) окон. Так как окно убывает одно положение, если другое окно получает фокус, мы можем завершить z-порядок окон, если мы запускаем фоновый скрипт для наблюдения истории фокуса окон.
Решение ниже существует двух маленьких фоновых сценариев, для выполнения одновременно.
focus_history.py
set_z.py
фокус-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 __name__ == "__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
Сценарий использует обоих wmctrl
и xdotool
sudo apt-get install wmctrl xdotool
Сценарий 1 копии в пустой файл, сохраните его (точно!) как focus_history.py
Сценарий 2 копии в пустой файл, сохраните его как set_z.py
в том же самом каталоге как сценарий 1.
В главном разделе сценария, в строке:
proc = "gedit"
замена "gedit"
названием процесса Вашего приложения (между кавычками)
Тестовый прогон сценарий: Прежде, чем открыть любые (дополнительные) окна, запустите сценарий 1 командой:
python3 /path/to/focus_history.py & python3 /path/to/set_z.py
[Сценарий распознает окна, которые были сфокусированы, по крайней мере, однажды. Это будет иметь место, если на сценарии будут работать, входят в систему]
Как упомянуто, сценарии должны быть в одном и том же каталоге на том же уровне.
Теперь запустите вводные окна и посмотрите, как это ведет себя. Ваше приложение должно переместиться в (самый) фон, если это теряет фокус.
Если все хорошо работает, добавьте его для Запущения Приложений: Тире> Приложения Запуска> Добавляет. Добавьте команду:
/bin/bash -c "sleep 15 && python3 /path/to/focus_history.py & python3 /path/to/set_z.py"
С другой стороны, Вы могли установить сочетание клавиш для повышения окна определенных приложений, если оно существует, как объяснено здесь.
Это потребовало бы однако, чтобы иметь другой ярлык для возвращения к окну первого приложения,
Если...,
Вы установили бы один ярлык для переключения между двумя приложениями. Это однако было бы вне объема этого вопроса...