wmctrl не может изменить размер / переместить окна внутри скрипта

Я пытаюсь написать скрипт, который открывает кучу программ и перемещает / изменяет размеры окон на экране.

Например,

#!/bin/bash
zim
wmctrl -r Zim -b toggle,maximized_vert
wmctrl -r Zim -e 0,700,0,-1,-1

Я запускаю этот скрипт, окно развернуто и немного смещено вправо. Но если я заменю zim от firefox или же acroread, это не может переместить / изменить размер окна.

Это работает, если я наберу wmctrl в терминале, но я бы хотел, чтобы это было внутри скрипта. Я думаю, это как-то связано с тем, как firefox запоминает свое место на экране.

Изменить: я разместил

firefox
wmctrl -lG

внутри скрипта, и я получаю следующий вывод:

0x03800032  0 1168 347  750  731  briareos emacs@briareos
0x02a00002  0 -2020 -1180 1920 1080 briareos XdndCollectionWindowImp
0x02a00005  0 0    24   47   1056 briareos unity-launcher
0x02a00008  0 0    0    1920 24   briareos unity-panel
0x02a0000b  0 -420 -300 320  200  briareos unity-dash
0x02a0000c  0 -420 -300 320  200  briareos Hud
0x03c00011  0 59   52   900  1026 briareos Notes - Zim

Это означает, что скрипт не знает, что Firefox был запущен.

1 ответ

Решение

Проблема

Проблема в том, что в комбинации команд, которые вы используете, вам нужно "повезти", чтобы окно приложения появилось вовремя, для wmctrl приказы быть успешными.
Ваши команды, вероятно, будут работать большую часть времени для легких приложений, быстро запускаясь, но будут зависеть от других, таких как Inkscape, Firefox или Thunderbird.

Вы можете встроить перерыв на 5 или десять секунд, как вы это сделали (упомянуто в комментариях), но либо вам придется ждать дольше, чем необходимо, либо он все равно сломается, если ваш процессор занят, а окно "позже, чем обычный".

Решение

Решение состоит в том, чтобы включить процедуру в ваш сценарий, ожидая появления окна в выходных данных wmctrl -lpи затем выполните команду, чтобы развернуть окно.

в python Пример ниже, я использовал xdotool изменить размер окна, немного более надежный в моем опыте, чем wmctrl сделать работу:

#!/usr/bin/env python3
import subprocess
import getpass
import time
import sys

app = sys.argv[1]

# to only list processes of the current user
user = getpass.getuser()
get = lambda x: subprocess.check_output(x).decode("utf-8")
# get the initial window list
ws1 = get(["wmctrl", "-lp"]); t = 0
# run the command to open the application
subprocess.Popen(app)

while t < 30:
    # fetch the updated window list, to see if the application's window appears
    ws2 = [(w.split()[2], w.split()[0]) for w in get(["wmctrl", "-lp"]).splitlines() if not w in ws1]
    # see if possible new windows belong to our application
    procs = sum([[(w[1], p) for p in get(["ps", "-u", user]).splitlines() \
              if app[:15].lower() in p.lower() and w[0] in p] for w in ws2], [])
    # in case of matches, move/resize the window
    if len(procs) > 0:
        subprocess.call(["xdotool", "windowsize", "-sync", procs[0][0] , "100%", "100%"])
        break
    time.sleep(0.5)
    t = t+1

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

  1. Скрипт нуждается в обоих wmctrl а также xdotool:

    sudo apt-get install wmctrl xdotool
    
  2. Скопируйте скрипт в пустой файл, сохраните его как resize_window.py

  3. Тест - запустить скрипт с приложением в качестве аргумента, например:

    python3 /path/to/resize_window.py firefox
    

Заметки

  • Если вы используете его как скрипт в Startup Applications, есть небольшая вероятность wmctrl Команда для получения списка окон выполняется слишком рано. Если вы столкнулись с проблемой, нам нужно добавить try/except для всей процедуры. Если это так, пожалуйста, дайте мне знать.
Другие вопросы по тегам