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
Как пользоваться
Скрипт нуждается в обоих
wmctrl
а такжеxdotool
:sudo apt-get install wmctrl xdotool
Скопируйте скрипт в пустой файл, сохраните его как
resize_window.py
Тест - запустить скрипт с приложением в качестве аргумента, например:
python3 /path/to/resize_window.py firefox
Заметки
- Если вы используете его как скрипт в Startup Applications, есть небольшая вероятность
wmctrl
Команда для получения списка окон выполняется слишком рано. Если вы столкнулись с проблемой, нам нужно добавитьtry
/except
для всей процедуры. Если это так, пожалуйста, дайте мне знать.