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

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 или 10 секунд, как вы сделали (упомянули в комментариях), но вам либо придется ждать дольше, чем необходимо, либо она все равно прервется, если ваш процессор занят, а окно «позже обычного».

Решение

Решением в таком случае будет включение в скрипт процедуры, которая будет ожидать появления окна в выходных данных 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для всей процедуры. Если это так, пожалуйста, дайте мне знать.

Связанный контент