web-dev-qa-db-fra.com

wmctrl ne parvient pas à redimensionner / déplacer des fenêtres dans un script

J'essaie d'écrire un script qui ouvre un tas de programmes et déplace/redimensionne les fenêtres à l'écran.

Par exemple,

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

Je lance ce script, la fenêtre est maximisée et déplacée un peu à droite. Mais, si je remplace zim par firefox ou acroread, la fenêtre ne pourra pas être déplacée/redimensionnée.

Cela fonctionne si je tape wmctrl dans le terminal, mais je l’aimerais dans le script . Je pense que cela doit avoir quelque chose à voir avec la façon dont firefox se souvient de sa place sur l'écran.

Edit: J'ai placé

firefox
wmctrl -lG

à l'intérieur du script et j'obtiens le résultat suivant:

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

Cela signifie que le script ne sait pas que Firefox a été lancé.

2
Magicsowon

Le problème

Le problème est que, dans la combinaison de commandes que vous utilisez, vous devez être "chanceux" pour que la fenêtre de l'application apparaisse à temps, pour que les commandes wmctrl réussissent.
Vos commandes fonctionneront probablement la plupart du temps pour les applications légères, à démarrage rapide, mais se briseront avec d’autres, comme Inkscape, Firefox ou Thunderbird.

Vous pouvez créez une pause de 5 ou 10 secondes, comme vous l'avez fait (mentionné dans les commentaires), mais vous devez soit attendre plus longtemps que nécessaire, soit cesser après si votre processeur est occupé et la fenêtre est "plus tard que d'habitude".

La solution

La solution consiste alors à inclure une procédure dans votre script, en attendant que la fenêtre apparaisse dans le résultat de wmctrl -lp, puis à exécuter la commande pour agrandir la fenêtre.

Dans l'exemple python ci-dessous, j'ai utilisé xdotool pour redimensionner la fenêtre, un peu plus robuste selon mon expérience que wmctrl pour effectuer le travail:

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

Comment utiliser

  1. Le script nécessite à la fois wmctrl et xdotool:

    Sudo apt-get install wmctrl xdotool
    
  2. Copiez le script dans un fichier vide, enregistrez-le sous le nom resize_window.py

  3. Test: exécutez le script avec l’application comme argument, par exemple:

    python3 /path/to/resize_window.py firefox
    

Remarques

  • Si vous l'utilisez en tant que script dans les applications de démarrage, la commande wmctrl permettant d'extraire la liste des fenêtres a une petite chance de s'exécuter trop tôt. Si vous rencontrez un problème, nous devons ajouter un try/except pour toute la procédure. Si oui, s'il vous plaît faites le moi savoir.
3
Jacob Vlijm