Isso pode ser feito muito bem, mas você precisa de um pouco de compreensão sobre Unity / viewports. Espero que a história abaixo seja compreensível, se não, por favor deixe um comentário.
O script abaixo pode ser usado para abrir uma janela de qualquer aplicativo em qualquer um dos seus viewports, em qualquer posição, se você o executar com os argumentos corretos. O script é uma versão editada de este , mas agora preparado para colocar janelas na área de trabalho virtual em>.
1. Entendendo viewports e coordenadas de janela
Espaços de trabalho na unidade
No Unity, ao contrário de outros gerenciadores de janelas, você tem apenas um espaço de trabalho de abrangência, que é dividido em viewports. No seu caso, sua área de trabalho é dividida em oito viewports.
Como a posição das janelas é definida
A posição da janela, como a saída do comando:
wmctrl -lG
(you need to have wmctrl installed to run the command)
é descrito como a posição relativa ao canto superior esquerdo da janela de visualização atual :
Então, se você está na viewport 1
:
uma janela na janela de visualização 2 pode ser posicionada em, e. 1700 (x-wise) x 500 (y-wise)
(minha tela é 1680x1050)
Noentanto,sevocêestivernaviewport6:
amesmajanelaseriaposicionadaem20(x),-550(y)
O uso correto dessas coordenadas é importante para executar o script com os argumentos corretos, conforme descrito abaixo:
2. Como usar o script
O script abaixo pode ser usado para colocar uma nova janela de uma aplicação em sua área de trabalho virtual (abrangendo).
-
Certifique-se de que
wmctrl
esteja instalado:sudo apt-get install wmctrl
-
Copie o script abaixo em um arquivo vazio, salve-o como
setwindow
(sem extensão) em~/bin
. Crie o diretório, se ainda não existir. Torne o script executável . -
Se você acabou de criar
~/bin
, execute o comandosource ~/.profile
ou efetue logout / in para disponibilizar o diretório em$PATH
. -
Teste o comando:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size>
por exemplo,
setwindow gedit 100 100 200 200
Uma janela do gedit deve aparecer na viewport atual.
Notas:
- Lembre-se de que nem todos os aplicativos permitem tamanhos de janela abaixo de uma determinada largura ou altura. A largura mínima de uma janela
gedit
no meu sistema é, por exemplo, appr. 470 px. - O script só funciona bem se a janela todo couber na janela de exibição de destino, escolha suas coordenadas / tamanhos de acordo. Lembre-se também que o Unity Launcher e o painel usam algum espaço (!) Que pode influenciar a posição da janela.
- Use
<x_position>
negativo para colocar janelas à esquerda da (s) janela (s) de visualização atual (s) - Use
<y_position>
negativo para colocar as janelas acima da (s) janela (s) de visualização atual -
Para abrir novas janelas em diferentes viewports de uma só vez, você pode simplesmente encadear comandos. Observando a configuração da viewport no exemplo "Long story", se eu estiver na viewport 1, posso abrir as janelas do gedit na viewport 1, 2, 3 e 4 com o 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
O script
#!/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: a versão preguiçosa
Caso você prefira apenas inserir coordenadas e tamanho, simplesmente como se fosse abrir uma janela na viewport atual, e dar a viewport alvo como um argumento (sem ter que calcular nada), então use a versão abaixo ...
Se você configurá-lo como a primeira versão do script, poderá executá-lo com o comando:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport>
Um exemplo: para abrir uma janela Google-Chrome
posicionada em 20, 20
, tamanho 300x300
, em viewport 5
:
setwindow google-chrome 20 20 300 300 5
A configuração é praticamente igual à primeira versão do script. Note que este script só funciona corretamente se a janela definida (posição / tamanho) couber completamente dentro da viewport desejada.
O script:
#!/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
Abrindo janelas de aplicativos com argumentos
Para finalizar o trabalho, responda sua pergunta completamente:
Se você executar o script como, por exemplo:
setwindow google-chrome 20 20 300 300 5
ele abrirá uma janela padrão nos desktops visados.
Com a versão mais recente do script, no entanto, você pode adicionar um argumento adicional para abrir a janela do aplicativo, por exemplo, um url
:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport> <(optional)_argument>
por exemplo:
setwindow google-chrome 0 0 600 600 3 "--new-window http://askubuntu.com"
Se o argumento (extra) contiver espaços, use aspas. O exemplo acima abrirá uma janela google-chrome
na viewport 3, abrindo o url
http://askubuntu.com
.
Você pode encadear comandos para abrir várias janelas / URLs em diferentes áreas de trabalho em um comando, por exemplo:
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"