J'essaie d'écrire un script pour identifier toutes les fenêtres chrome ouvertes et les déplacer dans une disposition en grille sur un grand écran
Je ne sais pas comment trouver les meilleures résolutions, alors j'allais les ajouter manuellement à un tableau. Ainsi, si la fenêtre 1 chrome était disponible, maximisez-la si 2 chrome fenêtres disponibles puis aller à un tableau pour les tailles pour cela?
Pour le moment, je peux déplacer toutes les fenêtres de l'écran (mon écran est alors cassé) mais je peux voir comment déplacer uniquement les écrans chrome?
Le script ci-dessous contient quelques idées que j'ai eues, mais veuillez indiquer la direction correcte car pour le moment, le script ne fonctionne pas.
#!/bin/bash
#Chrome window crontroller
# Monitor 1920 X 1800
# Choose array for number of screens available
# Different screen positions
G=0
win1_X=5; win1_Y=24; win1_W=639; win1_H=499;
win2_X=642; win2_Y=24; win2_W=639; win2_H=499;
win3_X=1280; win3_Y=24; win3_W=639; win3_H=499;
win4_X=5; win4_Y=552; win4_W=639; win4_H=499;
ChromesAvailable()
{
CA=$(wmctrl -lx | grep Chromium | wc -l)
}
GetNumOfChrome()
{
WID=$(wmctrl -l | grep n | awk '{print$1}')
#echo "INFO: window id = $WID"
}
PlaceWindow()
{
X=${n}_X; Y=${n}_Y; W=${n}_W; H=${n}_H;
wmctrl -i -r "$WID" -e $G,${!X},${!Y},${!W},${!H}
}
if [ "$#" -gt 0 ]; then
case "$1" in
*)
echo "ERROR: invalid option $1"
echo "see --help for usage"
exit 1
;;
esac
exit 0
else
for n in win{1..4}; do
GetNumOfChrome
PlaceWindow
done
fi
Edité - Pour mieux expliquer les choses :-)
Utiliser grep n
chargera toutes les fenêtres ouvertes du système. J'ai donc essayé d'utiliser grep Chromimum
mais le script n'aime pas cela.
GetNumOfChrome()
{
WID=$(wmctrl -l | grep n | awk '{print$1}')
#echo "INFO: window id = $WID"
}
Une approche différente consiste à organiser les fenêtres sous forme de grille prédéfinie (personnalisable) (colonnes/lignes).
Un exemple:
réarrangé en (cols
réglé sur 3, rows
réglé sur 2):
réarrangé en (cols
réglé sur 4, rows
réglé sur 2):
Le script ci-dessous peut être utilisé pour cela. Comme indiqué, le nombre de colonnes et de lignes peut être défini, ainsi que le remplissage entre les fenêtres. Le script calcule ensuite les positions dans lesquelles les fenêtres doivent être disposées, ainsi que leurs tailles.
La commande wmctrl
montre certaines particularités lorsqu’elle est utilisée pour déplacer des fenêtres vers ou très près du lanceur ou du panneau. Donc les marges:
left_margin = 70; top_margin = 30
ne peut pas être mis à zéro. Vous devez respecter une distance minimale de quelques px avec le panneau et le lanceur. Je suggérerais de laisser les deux marges - valeurs telles qu'elles sont. Toutes les autres valeurs, marges, colonnes et rangées avec lesquelles vous pouvez jouer et le définir à votre guise.
#!/usr/bin/env python3
import subprocess
import getpass
import sys
#--- set your preferences below: columns, rows, padding between windows, margin(s)
cols = 2; rows = 2; padding = 10; left_margin = 70; top_margin = 30
#---
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def get_res():
xr = get("xrandr").split(); pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
# get resolution
res = get_res()
# define (calculate) the area to divide
area_h = res[0] - left_margin; area_v = res[1] - top_margin
# create a list of calculated coordinates
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
# calculate the corresponding window size, given the padding, margins, columns and rows
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
# find windows of the application, identified by their pid
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
print(pids, w_list, coords)
# remove possibly maximization, move the windows
for n, w in enumerate(w_list):
data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+w+" -e 0,"+data
for cmd in [cmd1, cmd2, cmd3]:
subprocess.Popen(["/bin/bash", "-c", cmd])
wmctrl
est installé :)rearrange_windows.py
Exécutez-le à l'aide de la commande:
python3 /path/to/rearrange_windows.py <application>
exemple: pour réorganiser chromium
fenêtres:
python3 /path/to/rearrange_windows.py chromium
réorganiser chrome
fenêtres
python3 /path/to/rearrange_windows.py chrome
Le script peut être utilisé pour placer les fenêtres de n'importe quelle application dans une grille, car le nom du processus de l'application est utilisé comme argument.
ci-dessous une version dynamique du script, comme demandé dans un commentaire. Cette version du script calcule le nombre de colonnes et de lignes en fonction du nombre de fenêtres. Les proportions de la ou des fenêtres réarrangées sont similaires à celles de l’écran.
La configuration et l'utilisation sont à peu près les mêmes que celles de la version ci-dessus, seul le nombre de colonnes et de lignes est maintenant défini automatiquement.
#!/usr/bin/env python3
import subprocess
import getpass
import sys
import math
#--- set your preferences below: padding between windows, margin(s)
padding = 10; left_margin = 70; top_margin = 30
#---
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def get_res():
xr = get("xrandr").split(); pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
# find windows of the application, identified by their pid
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
# calculate the columns/rows, depending on the number of windows
cols = math.ceil(math.sqrt(len(w_list))); rows = cols
# define (calculate) the area to divide
res = get_res()
area_h = res[0] - left_margin; area_v = res[1] - top_margin
# create a list of calculated coordinates
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
# calculate the corresponding window size, given the padding, margins, columns and rows
if cols != 0:
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
# remove possibly maximization, move the windows
for n, w in enumerate(w_list):
data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+w+" -e 0,"+data
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
Voir ci-dessous les exemples avec un nombre variable de fenêtres ouvertes:
Recherche des fenêtres spécifiques
La commande:
wmctrl -lp
liste toutes les fenêtres, dans le format:
0x19c00085 0 14838 jacob-System-Product-Name *Niet-opgeslagen document 1 - gedit
où la première colonne est l'identifiant unique de la fenêtre et la troisième colonne le pid de l'application propriétaire de la fenêtre.
La commande:
ps -e
liste tous les processus, dans le format:
14838 ? 00:00:02 gedit
où la première colonne est le pid de l'application, la dernière est le nom du processus.
En comparant ces deux listes, on peut trouver toutes les fenêtres (id of-) appartenant à une application spécifique (appelée w_list
dans le script, à la suite de la ligne 17/18 du script):
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
Calcul du nombre de lignes/colonnes
Cela implique que le nombre de colonnes et de rangées est égal à la racine carrée arrondie du nombre de fenêtres à réorganiser. Cela se fait à la ligne 20:
cols = math.ceil(math.sqrt(len(w_list))); rows = cols
Calcul de la taille et de la position de la fenêtre
Une fois que nous avons le nombre de colonnes, tout ce que nous avons à faire est de diviser la zone disponible (résolution d'écran - marge gauche/marge supérieure) dans les colonnes/lignes et nous obtenons le taille de la fenêtre ciblée, qui est puis diminué de la padding
, comme indiqué dans la tête du script:
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
Les positions horizontales (x) sont le résultat du ou des produits du type taille de la fenêtre horizontale (remplissage compris) multiplié par le numéro de colonne, dans une plage du nombre de Colonnes. par exemple: si j'ai 3 colonnes de 300 px, les positions x résultantes sont:
[0, 300, 600]
Les positions verticales (y) sont calculés de la même manière. Les deux listes sont ensuite combinées dans une liste de coordonnées dans laquelle les fenêtres seront réorganisées.
Ceci est fait dans les lignes 26-28 du script:
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
La réorganisation réelle enfin (après optimisation des fenêtres éventuellement maximisées) est effectuée à partir de la ligne 33 et plus.
Le script ci-dessous met en mosaïque un nombre arbitraire de fenêtres chrome ou chromées dans une grille Nx2 (N lignes, 2 colonnes), où N dépend du nombre de fenêtres ouvertes. S'il n'y a qu'une seule fenêtre, cette fenêtre sera maximisée (ou non maximisée si elle est déjà maximisée).
#!/usr/bin/env bash
#################################################
# Exit if there are no running chrome processes #
#################################################
pgrep "chrom[e|ium]" &>/dev/null ||
echo "No Chrom[e|ium] processes are running" 1>&2 && exit
#########################
# Get screen dimensions #
#########################
read width x height < <(xrandr | grep -Po 'current\s*\K.*?(?=,)' )
###################################################################
# Get the names of all Chrome windows. I am using PIDs because #
# searching by name will match anything with chrome/chromium in #
# the title, not only chromium windows. It also matches a firefox #
# window open on this AU question, for example. #
###################################################################
mapfile -t windows <
<(wmctrl -pl | grep -f <(pgrep "chrom[e|ium]") |
cut -d' ' -f1)
####################################
# Get the number of Chrome windows #
####################################
numofwins=${#windows[@]}
#########################################
# Initialize the x and y positions to 0 #
#########################################
x=0
y=0
#############################################
# Get 1/2 the number of windows, rounded up #
#############################################
halfwins=$(printf "%.f" "$(echo $numofwins/2 | bc -l |
awk '{print int($1+0.5)}')")
######################################################
# If there's only one window, maximize/unmaximize it #
######################################################
[[ $numofwins -eq 1 ]] &&
wmctrl -i -r "${windows[@]}" -b toggle,maximized_vert,maximized_horz &&
exit;
##########################################################################
# The height of each window will be the height of the display divided by #
# half the number of windows #
##########################################################################
winheight=$(printf "%.f" "$(echo $height/$halfwins | bc -l)")
##################################################################
# The width of each window will be half the width of the display #
##################################################################
winwidth=$(($width/2))
##################################
# Iterate over each window found #
##################################
for winID in "${windows[@]}"
do
########################################
# Increment a counter. This is used to #
# know when we should change rows. #
########################################
let c++
###############################
# Position the current window #
###############################
wmctrl -i -r "$winID" -e 0,$x,$y,$winwidth,$winheight
##################################################
# If the counter is a multiple of 2, change rows #
##################################################
if [[ $((c % 2)) -eq 0 ]]
then
y=$((y+$winheight+2))
x=0
#######################################
# If it isn't, move to the right only #
#######################################
else
x=$((x+$winwidth+2))
fi
done