У меня есть выполнение сценария wmctrl -x -a "$1"
. Это поднимает окно, переданное как аргумент сценарию, например:
wmctrl -x -a "Firefox"
активирует Firefox.
Однако с приложениями, которые имеют несколько окон, это не поднимает последние используемые окна. Полагайте, что у меня есть 3 окна, открытые в LibreOffice Writer
, названный 'Документом 1', 'Документ 2' и 'Документ 3' и я находимся на Документе 3, и я перемещаюсь в другое приложение. Выполнение сценария поднимает 'Документ 1' и не 'Документ 3', который в последний раз использовался.
Любой флаг для решения этой проблемы в wmctrl
?
По запросу, расколу другого ответа, добавленного с новым разделом.
Как повысить последний раз сфокусированное окно приложения
Как упомянуто в моем комментарии, в настоящее время, нет никакой истории фокуса окон. Это означает, что, если нам нужен он, мы должны создать его сами. Первый сценарий ниже точно делает это; Это отслеживает в настоящее время фокусируемое окно и хранит историю в крошечном файле, обновленном однажды в секунду. Порядок строк является также порядком фокуса; верхняя строка представляет последнее сфокусированное окно, последняя строка "самое старое".
Чтобы заставить сценарий повысить последний раз сфокусированное окно приложения, все, что мы должны сделать, должно считать строки сверху донизу, найти первое вхождение окна приложения и повысить его. Это точно, что второй сценарий делает при выполнении его с WM_CLASS
из разыскиваемого окна.
Фоновый сценарий, отслеживающий на истории фокуса. Этот сценарий является точной копией первой здесь:
#!/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))
Скопируйте сценарий в пустой файл, сохраните его как focus_history.py
Сценарий для повышения последнего сфокусированного окна приложения.
#!/usr/bin/env python3
import os
import subprocess
import sys
lookfor = sys.argv[1]
winhistory = os.environ["HOME"]+"/.focus_history"
for l in open(winhistory):
wid = l.split()[0]
wmclass = subprocess.check_output(
["xprop", "-id", wid, "WM_CLASS"]
).decode("utf-8").strip()
if lookfor in wmclass:
subprocess.check_output(["wmctrl", "-ia", wid])
break
Сохраните его как raise_recent.py
.
удостовериться wmctrl
установлен:
sudo apt install wmctrl
Тестовый прогон первый сценарий как краткое описание с командой:
python3 /path/to/focus_history.py
N.B удостоверяются, что сценарий запускается перед другими открытыми окнами еще окна будут только зарегистрированы (конечно), после того как они получают свой первый фокус.
Назовите второй сценарий с командой (например).
python3 /path/to/raise_recent.py gedit
... повысить последний раз сфокусированное окно gedit
.
Если все хорошо работает, добавьте первый сценарий для Запущения Приложений. Отметьте однако, что, вероятно, необходимо добавить повреждение перед сценарием, чтобы запустить, предотвратить wmctrl
повреждаться. (Хотя сценарий не был должен, так как он обрабатывает возможное исключение).
Именно.