Cela peut être très bien fait, mais vous avez besoin de comprendre Unity / viewports. J'espère que l'histoire ci-dessous est compréhensible, sinon, veuillez laisser un commentaire.
Le script ci-dessous peut être utilisé pour ouvrir une fenêtre de n'importe quelle application sur n'importe laquelle de vos fenêtres, à n'importe quelle position, si vous l'exécutez avec les bons arguments. Le script est une version modifiée de celui-ci , mais maintenant prêt à placer des fenêtres sur le bureau virtuel couvrant .
1. Comprendre les fenêtres et les coordonnées des fenêtres
Espaces de travail dans Unity
Dans Unity, contrairement à d'autres gestionnaires de fenêtres, vous n'avez en fait qu'un seul espace de travail s'étendant, qui est divisé en fenêtres. Dans votre cas, votre espace de travail est divisé en huit fenêtres.
Comment la position des fenêtres est définie
La position de la fenêtre, en sortie de la commande:
wmctrl -lG
(you need to have wmctrl installed to run the command)
est décrit comme la position, par rapport au coin supérieur gauche de la fenêtre courante :
Donc, si vous êtes sur la fenêtre d'affichage 1
:
une fenêtre sur la fenêtre d'affichage 2 pourrait être positionnée par exemple sur 1700 (x-sage) x 500 (y-sage)
(mon écran est 1680x1050)
Cependant, si vous êtes sur la fenêtre 6:
la même fenêtre serait positionnée sur 20 (x), -550 (y)
Il est important d'utiliser correctement ces coordonnées pour exécuter le script avec les bons arguments, comme décrit ci-dessous:
2. Comment utiliser le script
Le script ci-dessous peut être utilisé pour placer une nouvelle fenêtre d'une application sur votre espace de travail virtuel (s'étendant).
Assurez-vous qu'il wmctrl
est installé:
sudo apt-get install wmctrl
Copiez le script ci-dessous dans un fichier vide, enregistrez-le sous setwindow
(sans extension) dans ~/bin
. Créez le répertoire s'il n'existe pas encore. Rendez le script exécutable .
- Si vous venez de créer
~/bin
, exécutez la commande source ~/.profile
ou déconnectez-vous pour rendre le répertoire disponible dans $PATH
.
Testez la commande:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size>
par exemple
setwindow gedit 100 100 200 200
Une fenêtre gedit devrait apparaître dans la fenêtre courante.
Remarques:
- Gardez à l'esprit que toutes les applications ne permettent pas des tailles de fenêtre inférieures à une certaine largeur ou hauteur. La largeur minimale d'une
gedit
fenêtre sur mon système est par exemple env. 470 px.
- Le script ne fonctionne correctement que si toute la fenêtre tient dans la fenêtre cible, choisissez vos coordonnées / tailles en conséquence. Gardez également à l'esprit que le lanceur Unity et le panneau utilisent un espace (!) Qui peut influencer la position de la fenêtre.
- Utilisez un négatif
<x_position>
pour placer les fenêtres à gauche de la ou des fenêtres actuelles
- Utilisez un négatif
<y_position>
pour placer les fenêtres au-dessus des fenêtres actuelles
Pour ouvrir simultanément de nouvelles fenêtres sur différentes fenêtres, vous pouvez simplement enchaîner les commandes. En regardant la configuration de la fenêtre dans l'exemple "Longue histoire", si je suis sur la fenêtre 1, je peux ouvrir des fenêtres gedit sur les fenêtres 1, 2, 3 et 4 avec la commande:
setwindow gedit 100 100 200 200&&setwindow gedit 1780 100 200 200&&setwindow gedit 3460 100 200 200&&setwindow gedit 5140 100 200 200
Le scénario
#!/usr/bin/env python3
import subprocess
import time
import sys
app = sys.argv[1]
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
ws1 = get("wmctrl -lp"); t = 0
subprocess.Popen(["/bin/bash", "-c", app])
# fix exception for Chrome (command = google-chrome-stable, but processname = chrome)
app = "chrome" if "chrome" in app else app
while t < 30:
ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
if app in p and w[2] in p] for w in ws2]
if len(procs) > 0:
w_id = procs[0][0][1]
cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+procs[0][0][1]+" -e 0,"+sys.argv[2]+","+sys.argv[3]+","+sys.argv[4]+","+sys.argv[5]
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
EDIT: la version paresseuse
Dans le cas où vous préférez simplement entrer les coordonnées et la taille, tout comme si vous ouvriez une fenêtre sur la fenêtre actuelle et donniez la fenêtre cible comme argument (sans avoir à calculer quoi que ce soit), utilisez la version ci-dessous ...
Si vous le configurez comme la première version du script, vous pouvez l'exécuter avec la commande:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport>
Un exemple: pour ouvrir une Google-Chrome
fenêtre positionnée sur 20, 20
, taille 300x300
, sur fenêtre 5
:
setwindow google-chrome 20 20 300 300 5
La configuration est à peu près la même que la première version du script.
Notez également que ce script ne fonctionne correctement que si la fenêtre définie (position / taille) s'intègre complètement dans la fenêtre cible.
Le scénario:
#!/usr/bin/env python3
import subprocess
import time
import sys
app = sys.argv[1]
target_vp = int(sys.argv[6])
def get_res():
# get resolution
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
res = get_res()
def current(set_vp):
# get the current viewport
vp_data = subprocess.check_output(
["wmctrl", "-d"]
).decode("utf-8").split()
dt = [int(n) for n in vp_data[3].split("x")]
cols = int(dt[0]/res[0])
rows = int(dt[1]/res[1])
curr_vpdata = [int(n) for n in vp_data[5].split(",")]
curr_col = int(curr_vpdata[0]/res[0])
curr_row = int(curr_vpdata[1]/res[1])
curr_vp = curr_col+curr_row*cols+1
# calculate the vector to the origin from the current viewport (in resolution units)
vec_curr = vector(curr_vp, cols)
# calculate the vector to the origin from the targeted viewport
vec_set = vector(set_vp, cols)
# calculate the vector between current and targeted viewport
vec_relative = [vec_set[0] - vec_curr[0],
vec_set[1] - vec_curr[1]]
# calculate needed correction (absolute)
relative = [vec_relative[0]*res[0],
vec_relative[1]*res[1]]
return relative
def vector(vp, cols):
rem = vp%cols
vec_x = rem-1 if rem != 0 else cols-1
vec_y = int((vp-1)/cols)
return [vec_x, vec_y]
res = get_res() # nieuw
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
ws1 = get("wmctrl -lp"); t = 0
# check for additional arguments to run the application
try:
subprocess.Popen(["/bin/bash", "-c", app+" "+sys.argv[7]])
except IndexError:
subprocess.Popen(["/bin/bash", "-c", app])
# fix exception for Chrome (command = google-chrome-stable, but processname = chrome)
app = "chrome" if "chrome" in app else app
while t < 30:
ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
if app in p and w[2] in p] for w in ws2]
if len(procs) > 0:
w_id = procs[0][0][1]
cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
# calculate the correction, related to the current workspace, marge for launcher and panel
pos_x = int(sys.argv[2]); pos_y = int(sys.argv[3]); x_marge = 65; y_marge = 35
pos_x = pos_x if pos_x > x_marge else x_marge; pos_y = pos_y if pos_y > y_marge else y_marge
x_relative = pos_x+current(target_vp)[0]
y_relative = pos_y+current(target_vp)[1]
# correct possible inaccurately set width / height
x_size = res[0]; y_size = res[1]
set_width = int(sys.argv[4]); set_height = int(sys.argv[5])
width = set_width if set_width+x_marge+pos_x < x_size else x_size - pos_x - x_marge
height = set_height if set_height+y_marge+pos_y < y_size else y_size - pos_y - y_marge
cmd3 = "wmctrl -ir "+w_id+" -e 0,"+str(x_relative)+","+str(y_relative)+","+str(width)+","+str(height)
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
Ouverture de fenêtres d'application avec des arguments
Pour terminer le travail, en répondant complètement à votre question:
Si vous exécutez le script comme par exemple:
setwindow google-chrome 20 20 300 300 5
il ouvrira une fenêtre par défaut sur le (s) bureau (s) ciblé (s).
Cependant, avec la dernière version du script, vous pouvez ajouter un argument supplémentaire pour ouvrir la fenêtre de l'application, par exemple url
:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport> <(optional)_argument>
par exemple:
setwindow google-chrome 0 0 600 600 3 "--new-window http://askubuntu.com"
Si l'argument (extra) contient des espaces, utilisez des guillemets. L'exemple ci-dessus ouvrira une google-chrome
fenêtre dans la fenêtre 3, ouvrant le url
http://askubuntu.com
.
Vous pouvez chaîner des commandes pour ouvrir plusieurs fenêtres / URL sur différents espaces de travail en une seule commande, par exemple:
setwindow google-chrome 0 0 600 600 8 "--new-window http://askubuntu.com"&&setwindow google-chrome 0 0 600 600 7 "--new-window www.google.com"
wmctrl
, qui est comme un logiciel pour contrôler les fenêtres via un script ou un terminal. Mais comme pour le redémarrage d'une fenêtre, cela pourrait être un peu plus difficile