Перенаправление команды для запуска приложения
Большинство приложений открывают свое окно на экране, с которого они были инициированы (из Dash или из панели запуска). Однако некоторые приложения этого не делают, но их можно заставить, перенаправив команду для запуска приложения с помощью приведенного ниже сценария. Для этого вам нужно будет отредактировать соответствующий .desktop
файл (лаунчер).
Настройка кажется немного сложной, но если следовать процедуре («Как использовать»), она не должна быть слишком сложной.
Как это работает
- Сценарий считывает положение мыши в тот момент, когда вы нажимаете на панель запуска или выбираете приложение из Dash, и определяет, на каком экране это (влево / вправо).
- Затем он ожидает появления нового окна, принадлежащего запущенному вами приложению (pid).
- Как только окно появляется, оно проверяет, соответствует ли положение окна (экрана) начальной позиции мыши (экрана).
- Если нет, он перемещает окно на экран, с которого вы запустили приложение. В большинстве случаев действие будет на (очень) ранней стадии существования окна, поэтому вы даже не заметите этого.
Проблема / решение
Есть один недостаток: если вы замените основную команду .desktop
файла командой для вызова этого скрипта, щелчок правой кнопкой мыши «открыть с помощью» не будет работать должным образом. В случае веб-браузера, такого как Google Chrome, это не будет большой проблемой. В других приложениях простым решением было бы добавить возможность открывать новое окно на текущем экране в виде ярлыка (см. Далее ниже).
Как пользоваться:
Скрипт использует wmctrl
и xautomation
:
sudo apt-get install xautomation
sudo apt-get install wmctrl
Создайте каталог, ~/bin
если он еще не существует.
Скопируйте скрипт в пустой файл, сохраните его как open_oncurrent
(без расширения) в~/bin
- Сделайте его исполняемым (!)
Скопируйте соответствующий .desktop
файл из /usr/share/applications
в ~/.local/share/applications
:
cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/google-chrome.desktop
Откройте локальную копию в ~/.local/share/applications
:
gedit ~/.local/share/applications/google-chrome.desktop
Отредактируйте файл (два варианта):
Чтобы изменить основную команду панели запуска:
Чтобы добавить опцию как ярлык (как на картинке выше):
найти строку:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;
замените его на:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;New window on this screen;
Затем добавьте следующий раздел в самый конец файла:
[New window on this screen Shortcut Group]
Name=New window on this screen
Exec=/bin/bash -c "open_oncurrent /usr/bin/google-chrome-stable"
TargetEnvironment=Unity
Как использовать с другими приложениями:
Точно так же вы можете применить решение к другим приложениям. Синтаксис команды для использования в .desktop
файле похож на пример:
Exec=/bin/bash -c "open_oncurrent <command>"
Небольшое дополнительное объяснение того, как обращаться с исключениями, находится в сценарии.
Сценарий
#!/usr/bin/env python3
import subprocess
import sys
import time
import getpass
t = 0; user = getpass.getuser(); application = sys.argv[1]
"""
In most cases, the command to run an application is the same as the process
name. There are however exceptions, to be listed below, if you use these appli-
cations i.c.w. this script. Just add an item to the list in the format:
["<command>", "<process_name>"],
"""
exceptions = [
["/usr/bin/google-chrome-stable", "chrome"],
]
try:
procname = [app[1] for app in exceptions if app[0] == application][0]
except IndexError:
procname = application
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
# initial position of the mouse (click position)
start_pos = int(get("xmousepos").strip().split()[0])
# x- position of right side of the screen
x_res = [int(s.split("x")[0]) for s in get("xrandr").split() if s.endswith("+0+0")][0]
# current windows
start_windows = get("wmctrl -l")
# open application
subprocess.call(["/bin/bash", "-c", application+"&"])
while t < 30:
procs = get("ps -u "+user).splitlines()
new = [w for w in get("wmctrl -lpG").splitlines() if not w.split()[0] in start_windows]
match = sum([[line for line in procs if w.split()[2] in line and procname[:15] in line] for w in new], [])
if len(match) == 1:
data = new[0].split(); curr_pos = int(data[3]); compare = (start_pos > x_res, curr_pos > x_res)
if compare[0] == compare[1]:
pass
else:
if compare[0] == True:
data[3] = str(int(data[3])+x_res)
else:
data[3] = str(int(data[3])-x_res)
cmd1 = "wmctrl -r "+data[0]+" -b remove,maximized_vert,maximized_horz"
cmd2 = "wmctrl -ir "+data[0]+" -e 0,"+(",").join(data[3:7])
for cmd in [cmd1, cmd2]:
subprocess.Popen(["/bin/bash", "-c", cmd])
break
t = t + 1
time.sleep(0.5)