Ini bisa dilakukan dengan sangat baik, tetapi Anda perlu pemahaman tentang Unity / viewports. Saya harap cerita di bawah ini bisa dimengerti, jika tidak, silakan tinggalkan komentar.
Skrip di bawah ini dapat digunakan untuk membuka jendela aplikasi apa pun di salah satu viewports Anda, pada posisi apa pun, jika Anda menjalankannya dengan argumen yang benar. Script adalah versi yang diedit dari yang satu ini , tetapi sekarang siap untuk menempatkan windows pada desktop virtual yang merentang .
1. Memahami viewports dan koordinat jendela
Ruang kerja di Unity
Di Unity, tidak seperti window manager lainnya, Anda sebenarnya hanya memiliki satu ruang kerja spanning, yang dibagi menjadi viewports. Dalam kasus Anda, ruang kerja Anda dibagi menjadi delapan viewports.
Bagaimana posisi jendela didefinisikan
Posisi jendela, sebagai output dari perintah:
wmctrl -lG
(you need to have wmctrl installed to run the command)
digambarkan sebagai posisi, relatif terhadap sudut kiri atas viewport saat ini :
Jadi jika Anda berada di viewport 1
:
sebuah jendela di viewport 2 dapat diposisikan pada mis. 1700 (x-bijaksana) x 500 (y-bijaksana)
(layar saya 1680x1050)
Namun, jika Anda berada di viewport 6:
jendela yang sama akan diposisikan pada 20 (x), -550 (y)
Menggunakan koordinat ini dengan benar adalah penting untuk menjalankan skrip dengan argumen yang benar, seperti dijelaskan di bawah ini:
2. Cara menggunakan skrip
Script di bawah ini dapat digunakan untuk menempatkan jendela aplikasi baru di ruang kerja virtual Anda (spanning).
Pastikan wmctrl
sudah terpasang:
sudo apt-get install wmctrl
Salin skrip di bawah ini ke file kosong, simpan sebagai setwindow
(tanpa ekstensi) di ~/bin
. Buat direktori jika belum ada. Jadikan skrip dapat dieksekusi .
- Jika Anda baru saja dibuat
~/bin
, jalankan perintah source ~/.profile
atau keluar / masuk untuk membuat direktori tersedia di $PATH
.
Uji jalankan perintah:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size>
misalnya
setwindow gedit 100 100 200 200
Jendela gedit akan muncul di viewport saat ini.
Catatan:
- Ingatlah bahwa tidak semua aplikasi memungkinkan ukuran jendela di bawah lebar atau tinggi tertentu. Lebar minimum
gedit
jendela pada sistem saya adalah mis. Appr. 470 px.
- Script hanya berfungsi dengan baik jika seluruh jendela pas di viewport yang ditargetkan, pilih koordinat / ukuran Anda sesuai. Juga perhatikan bahwa Unity Launcher dan panel menggunakan beberapa ruang (!) Yang dapat memengaruhi posisi jendela.
- Gunakan negatif
<x_position>
untuk menempatkan jendela di sebelah kiri viewport saat ini
- Gunakan negatif
<y_position>
untuk menempatkan jendela di atas viewport saat ini
Untuk membuka jendela baru pada viewports yang berbeda sekaligus, Anda dapat dengan mudah mengaitkan perintah. Melihat pengaturan viewport dalam contoh "Panjang cerita", Jika saya di viewport 1, saya dapat membuka jendela gedit di viewport 1, 2, 3 dan 4 dengan perintah:
setwindow gedit 100 100 200 200&&setwindow gedit 1780 100 200 200&&setwindow gedit 3460 100 200 200&&setwindow gedit 5140 100 200 200
Naskah
#!/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: versi malas
Jika Anda lebih suka memasukkan koordinat dan ukuran, seperti seolah-olah Anda akan membuka jendela pada viewport saat ini, dan memberikan viewport yang ditargetkan sebagai argumen (tanpa harus menghitung apa pun), maka gunakan versi di bawah ini ...
Jika Anda mengaturnya seperti versi pertama skrip, Anda dapat menjalankannya dengan perintah:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport>
Contoh: untuk membuka Google-Chrome
jendela yang diposisikan pada 20, 20
, ukuran 300x300
, pada viewport 5
:
setwindow google-chrome 20 20 300 300 5
Penyiapannya hampir sama dengan skrip versi pertama.
Perhatikan bahwa skrip ini juga hanya berfungsi dengan benar jika jendela yang ditentukan (posisi / ukuran) cocok sepenuhnya dalam viewport yang ditargetkan.
Naskah:
#!/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
Membuka jendela aplikasi dengan argumen
Untuk menyelesaikan pekerjaan, jawab pertanyaan Anda sepenuhnya:
Jika Anda menjalankan skrip seperti misalnya:
setwindow google-chrome 20 20 300 300 5
itu akan membuka jendela default pada desktop yang ditargetkan.
Namun, dengan skrip versi terbaru, Anda dapat menambahkan argumen tambahan untuk membuka jendela aplikasi, misalnya url
:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport> <(optional)_argument>
misalnya:
setwindow google-chrome 0 0 600 600 3 "--new-window http://askubuntu.com"
Jika argumen (ekstra) berisi spasi, gunakan tanda kutip. Contoh di atas akan membuka google-chrome
jendela pada viewport 3, membuka jendela url
http://askubuntu.com
.
Anda dapat mengaitkan perintah untuk membuka banyak jendela / url pada ruang kerja yang berbeda dalam satu perintah, misalnya:
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
, yang seperti perangkat lunak untuk mengendalikan windows melalui skrip atau terminal. Tetapi untuk memulai kembali sebuah jendela, itu mungkin sesuatu yang sedikit lebih menantang