Це можна зробити дуже добре, але вам потрібно трохи зрозуміти Unity / viewports. Я сподіваюсь, що історія нижче зрозуміла, якщо ні, будь ласка, залиште коментар.
Сценарій нижче може бути використаний для відкриття вікна будь-якої програми на будь-якому з ваших вікон перегляду, у будь-якій позиції, якщо ви запускаєте його з правильними аргументами. Сценарій є відредагованою версією цієї , але тепер готова розмістити вікна на віртуальному робочому столі .
1. Розуміння вікон перегляду та координат вікон
Робочі простори в єдності
У Unity, на відміну від інших менеджерів вікон, у вас є лише одна робоча область, що охоплює, яка поділяється на вікна перегляду. У вашому випадку ваша робоча область розділена на вісім вікон перегляду.
Як визначається положення вікон
Положення вікна, як вихід команди:
wmctrl -lG
(you need to have wmctrl installed to run the command)
описується як положення відносно верхнього лівого кута поточного огляду :
Отже, якщо ви перебуваєте у вікні перегляду 1
:
вікно у вікні перегляду 2, яке може бути розміщене, наприклад, 1700 (x-мудрий) x 500 (y-мудрий)
(мій екран - 1680x1050)
Однак якщо ви перебуваєте у вікні перегляду 6:
те саме вікно було б розміщене на 20 (x), -550 (y)
Використання цих координат важливо для запуску сценарію з правильними аргументами, як описано нижче:
2. Як користуватися сценарієм
Сценарій нижче може бути використаний для розміщення нового вікна програми на вашій віртуальній робочій області.
Переконайтесь, що wmctrl
встановлено:
sudo apt-get install wmctrl
Скопіюйте сценарій нижче в порожній файл, збережіть його як setwindow
(без розширення) в ~/bin
. Створіть каталог, якщо він ще не існує. Зробіть сценарій виконуваним .
- Якщо ви тільки що створили
~/bin
, виконайте команду source ~/.profile
або вийдіть / увійдіть, щоб зробити доступний каталог $PATH
.
Тестовий запуск команди:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size>
напр
setwindow gedit 100 100 200 200
У поточному вікні перегляду повинно з’являтися вікно gedit.
Примітки:
- Майте на увазі, що не всі програми допускають розміри вікон нижче певної ширини чи висоти. Мінімальна ширина
gedit
вікна в моїй системі, наприклад, appr. 470 пікс.
- Сценарій чудово працює лише у тому випадку, якщо все вікно вміщається на цільовому вікні перегляду, відповідно вибирайте координати / розміри. Також майте на увазі, що панель запуску Unity та панель використовують деякий простір (!), Який може впливати на положення вікна.
- Використовуйте мінус,
<x_position>
щоб розмістити вікна зліва від поточних вікон перегляду
- Використовуйте мінус,
<y_position>
щоб розмістити вікна над поточними вікнами перегляду
Щоб відкрити нові вікна в різних областях перегляду одразу, можна просто ланцюжок команд. Переглядаючи налаштування вікна перегляду в прикладі "Довга історія", якщо я перебуваю у вікні перегляду 1, я можу відкрити вікна gedit у вікнах перегляду 1, 2, 3 та 4 за допомогою команди:
setwindow gedit 100 100 200 200&&setwindow gedit 1780 100 200 200&&setwindow gedit 3460 100 200 200&&setwindow gedit 5140 100 200 200
Сценарій
#!/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: лінива версія
У випадку, якщо ви хочете просто ввести координати та розмір, просто так, як якщо б ви відкрили вікно в поточному вікні перегляду та надали цільовий огляд перегляду як аргумент (без необхідності нічого обчислювати), то використовуйте наведену нижче версію ...
Якщо встановити його як першу версію сценарію, ви можете запустити його командою:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport>
Приклад: відкрити Google-Chrome
вікно, розміщене на 20, 20
, розмірі 300x300
, у вікні перегляду 5
:
setwindow google-chrome 20 20 300 300 5
Установка майже однакова як у першій версії сценарію.
Зверніть увагу, що також цей скрипт працює правильно, лише якщо визначене вікно (положення / розмір) повністю вписується в цільовий вікно перегляду.
Сценарій:
#!/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
Відкриття вікна програми з аргументами
Щоб закінчити роботу, повністю відповівши на ваше запитання:
Якщо ви запускаєте сценарій, наприклад:
setwindow google-chrome 20 20 300 300 5
це відкриє вікно за замовчуванням на цільовому робочому столі.
З останньою версією сценарію, однак, ви можете додати додатковий аргумент для відкриття вікна програми, наприклад url
:
setwindow <application> <x_position> <y_position> <horizontal_size> <vertical_size> <targeted_viewport> <(optional)_argument>
наприклад:
setwindow google-chrome 0 0 600 600 3 "--new-window http://askubuntu.com"
Якщо (додатковий) аргумент містить пробіли, використовуйте лапки. Наведений вище приклад відкриє google-chrome
вікно на вікні перегляду 3, відкривши вікно url
http://askubuntu.com
.
Ви можете зв'язати команди, щоб відкрити кілька вікон / URL-адрес на різних робочих просторах однією командою, наприклад:
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
, як програмне забезпечення для управління Windows через скрипт або термінал. А щодо перезапуску вікна, це може бути дещо більш складним завданням