Se puede hacer muy bien, pero necesita un poco de comprensión sobre Unity / viewports. Espero que la historia a continuación sea comprensible, si no, deje un comentario.
El siguiente script se puede usar para abrir una ventana de cualquier aplicación en cualquiera de sus ventanas gráficas, en cualquier posición, si la ejecuta con los argumentos correctos. El script es una versión editada de este , pero ahora está preparado para colocar ventanas en el escritorio virtual .
1. Comprender las ventanas gráficas y las coordenadas de la ventana
Espacios de trabajo en la unidad
En Unity, a diferencia de otros administradores de ventanas, en realidad solo tiene un área de trabajo que se divide, que se divide en ventanas gráficas. En su caso, su espacio de trabajo se divide en ocho ventanas gráficas.
Cómo se define la posición de las ventanas
La posición de la ventana, como la salida del comando:
wmctrl -lG
(you need to have wmctrl installed to run the command)
se describe como la posición, en relación con la esquina superior izquierda de la ventana gráfica actual :
Entonces, si está en la ventana gráfica 1
:
una ventana en la ventana gráfica 2 podría colocarse, por ejemplo, en 1700 (x-wise) x 500 (y-wise)
(mi pantalla es 1680x1050)
Sin embargo, si está en la ventana gráfica 6:
la misma ventana se colocaría en 20 (x), -550 (y)
Usar estas coordenadas correctamente es importante para ejecutar el script con los argumentos correctos, como se describe a continuación:
2. Cómo usar el script
La secuencia de comandos a continuación se puede utilizar para colocar una nueva ventana de una aplicación en su espacio de trabajo virtual (de expansión).
Asegúrese de que wmctrl
esté instalado:
sudo apt-get install wmctrl
Copie el script a continuación en un archivo vacío, guárdelo como setwindow
(sin extensión) en ~/bin
. Cree el directorio si aún no existe. Haga que el script sea ejecutable .
- Si acaba de crear
~/bin
, ejecute el comando source ~/.profile
o cierre la sesión / inicie sesión para que el directorio esté disponible $PATH
.
Prueba ejecutar el comando:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size>
p.ej
setwindow gedit 100 100 200 200
Debería aparecer una ventana gedit en la ventana gráfica actual.
Notas:
- Tenga en cuenta que no todas las aplicaciones permiten tamaños de ventana por debajo de cierto ancho o alto. El ancho mínimo de una
gedit
ventana en mi sistema es, por ejemplo, appr. 470 px.
- La secuencia de comandos solo funciona bien si toda la ventana se ajusta a la vista objetivo, elija sus coordenadas / tamaños en consecuencia. También tenga en cuenta que Unity Launcher y el panel usan algo de espacio (!) Que puede influir en la posición de la ventana.
- Use negativo
<x_position>
para colocar ventanas a la izquierda de las ventanas gráficas actuales
- Use negativo
<y_position>
para colocar ventanas sobre las ventanas de visualización actuales
Para abrir nuevas ventanas en diferentes ventanas gráficas a la vez, simplemente puede encadenar comandos. Mirando la configuración de la ventana gráfica en el ejemplo "Larga historia", si estoy en la ventana gráfica 1, puedo abrir las ventanas gedit en la ventana gráfica 1, 2, 3 y 4 con el comando:
setwindow gedit 100 100 200 200&&setwindow gedit 1780 100 200 200&&setwindow gedit 3460 100 200 200&&setwindow gedit 5140 100 200 200
La secuencia de comandos
#!/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
EDITAR: la versión perezosa
En caso de que prefiera ingresar solo las coordenadas y el tamaño, simplemente como si abriera una ventana en la vista actual, y diera la vista objetivo como argumento (sin tener que calcular nada), luego use la versión a continuación ...
Si lo configura como la primera versión del script, puede ejecutarlo con el comando:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport>
Un ejemplo: para abrir una Google-Chrome
ventana posicionada en 20, 20
, tamaño 300x300
, en la ventana gráfica 5
:
setwindow google-chrome 20 20 300 300 5
La configuración es más o menos la misma que la primera versión del script.
Tenga en cuenta que también este script solo funciona correctamente si la ventana definida (posición / tamaño) se ajusta completamente dentro de la ventana de visualización de destino.
La secuencia de comandos:
#!/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
Abrir ventanas de aplicaciones con argumentos
Para finalizar el trabajo, responde tu pregunta por completo:
Si ejecuta el script como, por ejemplo:
setwindow google-chrome 20 20 300 300 5
abrirá una ventana predeterminada en los escritorios de destino.
Sin embargo, con la última versión del script, puede agregar un argumento adicional para abrir la ventana de la aplicación, por ejemplo, un url
:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport> <(optional)_argument>
p.ej:
setwindow google-chrome 0 0 600 600 3 "--new-window http://askubuntu.com"
Si el argumento (extra) contiene espacios, use comillas. El ejemplo anterior abrirá una google-chrome
ventana en la ventana gráfica 3, abriendo el url
http://askubuntu.com
.
Puede encadenar comandos para abrir múltiples ventanas / URL en diferentes espacios de trabajo en un solo comando, por ejemplo:
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
, que es como un software para controlar ventanas a través de script o terminal. Pero en cuanto al reinicio de una ventana, eso podría ser un poco más desafiante