Примітка
Сценарій було зафіксовано / зафіксовано 16 січня 2017 року, виправляючи декілька застосунків, назва яких процес відрізняється від команди для запуску програми . Можливо, це трапляється періодично на додатках. Якщо хтось знайде його, будь ласка, залиште коментар.
Сценарій для запам'ятовування та відновлення розташування вікон та відповідних програм.
Сценарій нижче може бути запущений з двома варіантами. Скажімо, у вас розташування вікон, як показано нижче:
Щоб прочитати (запам'ятати) поточне розташування вікон та їх програм, запустіть сценарій з можливістю:
<script> -read
Потім закрийте всі вікна:
Потім, щоб налаштувати останнє запам'ятоване розташування вікон, запустіть його з опцією:
<script> -run
і останнє запам'ятоване розташування вікон буде відновлено:
Це також буде працювати після перезавантаження.
Поклавши ці дві команди під дві різні клавіші швидкого доступу, ви можете "записати" розташування вікон, вимкнути комп'ютер і згадати ту саму компоновку вікон після (наприклад) перезавантаження.
Що робить сценарій, а що ні
Запустити з опцією -read
- Сценарій використовує
wmctrl
для переліку всіх вікон, усіх робочих просторів, їхніх позицій, розмірів, програм, до яких належить
- Потім сценарій "перетворює" позиції вікна з відносних (у поточну робочу область, як у виході
wmctrl
) на абсолютні позиції, на ваших робочих робочих просторах. Тому неважливо, вікна, які ви хочете запам’ятати, знаходяться лише на одній робочій площі або розповсюджені на різних робочих просторах.
- Потім сценарій "запам'ятовує" поточну компоновку вікон, записуючи її у невидимий файл у вашому домашньому каталозі.
Запустити з опцією -run
- сценарій читає останнє запам'ятоване розташування вікон; він запускає відповідні програми, переміщує вікна у запам’ятовані положення, також за допомогою
wmctrl
Сценарій не запам'ятовує файли, які, можливо, можуть бути відкриті у вікнах, а також (наприклад) веб-сайти, відкриті у вікні браузера.
Випуски
Поєднання wmctrl
та Unity
має кілька помилок, кілька прикладів:
- Координати вікон, як прочитано,
wmctrl
відрізняються дещо формуючи команду розташування вікон, як згадується тут . Тому позиції, що відкликаються, можуть трохи відрізнятися від вихідних.
- Ці
wmctrl
команди працюють трохи непередбачувані , якщо край вікна дуже близько або Unity Launcher
або панель.
- Вікна, що запам'ятовуються, повинні знаходитися повністю в межах робочої області, щоб команда
wmctrl
розміщення працювала добре.
Деякі програми відкривають нові вікна за замовчуванням у тому ж вікні нової вкладки (як gedit
). Я це виправив gedit
, але будь ласка, зазначте, якщо ви знайдете більше винятків.
Сценарій
#!/usr/bin/env python3
import subprocess
import os
import sys
import time
wfile = os.environ["HOME"]+"/.windowlist"
arg = sys.argv[1]
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def check_window(w_id):
w_type = get("xprop -id "+w_id)
if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
return True
else:
return False
def get_res():
# get resolution and the workspace correction (vector)
xr = subprocess.check_output(["xrandr"]).decode("utf-8").split()
pos = xr.index("current")
res = [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
vp_data = subprocess.check_output(["wmctrl", "-d"]).decode("utf-8").split()
curr_vpdata = [int(n) for n in vp_data[5].split(",")]
return [res, curr_vpdata]
app = lambda pid: subprocess.check_output(["ps", "-p", pid, "-o", "comm="]).decode("utf-8").strip()
def read_windows():
res = get_res()
w_list = [l.split() for l in get("wmctrl -lpG").splitlines()]
relevant = [[w[2],[int(n) for n in w[3:7]]] for w in w_list if check_window(w[0]) == True]
for i, r in enumerate(relevant):
relevant[i] = app(r[0])+" "+str((" ").join([str(n) for n in r[1]]))
with open(wfile, "wt") as out:
for l in relevant:
out.write(l+"\n")
def open_appwindow(app, x, y, w, h):
ws1 = get("wmctrl -lp"); t = 0
# fix command for certain apps that open in new tab by default
if app == "gedit":
option = " --new-window"
else:
option = ""
# fix command if process name and command to run are different
if "gnome-terminal" in app:
app = "gnome-terminal"
elif "chrome" in app:
app = "/usr/bin/google-chrome-stable"
subprocess.Popen(["/bin/bash", "-c", app+option])
# 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:
time.sleep(0.5)
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,"+x+","+y+","+w+","+h
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
break
time.sleep(0.5)
t = t+1
def run_remembered():
res = get_res()[1]
try:
lines = [l.split() for l in open(wfile).read().splitlines()]
for l in lines:
l[1] = str(int(l[1]) - res[0]); l[2] = str(int(l[2]) - res[1] - 24)
open_appwindow(l[0], l[1], l[2], l[3], l[4])
except FileNotFoundError:
pass
if arg == "-run":
run_remembered()
elif arg == "-read":
read_windows()
Як налаштувати
Перш ніж почати, переконайтесь, що wmctrl
встановлено:
sudo apt-get install wmctrl
Потім:
- Скопіюйте скрипт у порожній файл, збережіть його як
recall_windows
у ~/bin
. Створіть каталог, якщо це необхідно. Якщо каталог ще не існував, запустіть source ~/.profile
або вийдіть із системи, або вийдіть із системи після входу. Зараз це буде в$PATH
- Зробіть сценарій виконуваним (!).
Тепер відкрийте кілька вікон, gedit
, firefox
або будь-який інший , і тест-запустити скрипт в терміналі з допомогою не виконавши команду (без префікса шляху потрібно):
recall_windows -read
закрийте вікна. Тепер запустіть у терміналі:
recall_windows -run
Тепер налаштування вікна слід відновити
Якщо все працює добре, додайте дві команди до клавіш швидкого доступу: Виберіть: Налаштування системи> "Клавіатура"> "Ярлики"> "Спеціальні ярлики". Клацніть "+" та додайте команди:
recall_windows -read
і
recall_windows -run
до двох різних клавіш швидкого доступу