Как я могу заставить wmctrl повысить последний раз fosused окно приложения?

У меня есть выполнение сценария wmctrl -x -a "$1". Это поднимает окно, переданное как аргумент сценарию, например:

wmctrl -x -a "Firefox" 

активирует Firefox.

Однако с приложениями, которые имеют несколько окон, это не поднимает последние используемые окна. Полагайте, что у меня есть 3 окна, открытые в LibreOffice Writer, названный 'Документом 1', 'Документ 2' и 'Документ 3' и я находимся на Документе 3, и я перемещаюсь в другое приложение. Выполнение сценария поднимает 'Документ 1' и не 'Документ 3', который в последний раз использовался.

Любой флаг для решения этой проблемы в wmctrl?

1
задан 29 October 2017 в 14:20

1 ответ

По запросу, расколу другого ответа, добавленного с новым разделом.

История фокуса окон

Как повысить последний раз сфокусированное окно приложения

Как упомянуто в моем комментарии, в настоящее время, нет никакой истории фокуса окон. Это означает, что, если нам нужен он, мы должны создать его сами. Первый сценарий ниже точно делает это; Это отслеживает в настоящее время фокусируемое окно и хранит историю в крошечном файле, обновленном однажды в секунду. Порядок строк является также порядком фокуса; верхняя строка представляет последнее сфокусированное окно, последняя строка "самое старое".

Чтобы заставить сценарий повысить последний раз сфокусированное окно приложения, все, что мы должны сделать, должно считать строки сверху донизу, найти первое вхождение окна приложения и повысить его. Это точно, что второй сценарий делает при выполнении его с WM_CLASS из разыскиваемого окна.

Сценарии

  1. Фоновый сценарий, отслеживающий на истории фокуса. Этот сценарий является точной копией первой здесь:

    #!/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

  2. Сценарий для повышения последнего сфокусированного окна приложения.

    #!/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.

Как использовать

  1. удостовериться wmctrl установлен:

    sudo apt install wmctrl
    
  2. Тестовый прогон первый сценарий как краткое описание с командой:

    python3 /path/to/focus_history.py
    

    N.B удостоверяются, что сценарий запускается перед другими открытыми окнами еще окна будут только зарегистрированы (конечно), после того как они получают свой первый фокус.

  3. Назовите второй сценарий с командой (например).

    python3 /path/to/raise_recent.py gedit
    

    ... повысить последний раз сфокусированное окно gedit.

  4. Если все хорошо работает, добавьте первый сценарий для Запущения Приложений. Отметьте однако, что, вероятно, необходимо добавить повреждение перед сценарием, чтобы запустить, предотвратить wmctrl повреждаться. (Хотя сценарий не был должен, так как он обрабатывает возможное исключение).

Именно.

2
ответ дан 7 December 2019 в 13:38

Другие вопросы по тегам:

Похожие вопросы: