Przekierowanie polecenia w celu uruchomienia aplikacji
Większość aplikacji otwiera okno na ekranie, z którego zostały zainicjowane (z poziomu Dasha lub programu uruchamiającego). Niektóre aplikacje jednak tego nie robią, ale można to zrobić, przekierowując polecenie, aby uruchomić aplikację za pomocą poniższego skryptu. Aby to zrobić, musisz edytować odpowiedni .desktop
plik (program uruchamiający).
Konfiguracja wydaje się nieco skomplikowana, ale jeśli zastosowana zostanie procedura („Jak korzystać”), nie powinno być wcale zbyt trudne.
Jak to działa
- Skrypt odczytuje pozycję myszy w momencie kliknięcia programu uruchamiającego lub wybierania aplikacji z Dash i określa, na którym ekranie jest (lewy / prawy).
- Kolejno czeka, aż pojawi się nowe okno, którego właścicielem jest uruchomiona aplikacja (pid).
- Po wyświetleniu okna sprawdza, czy pozycja okna (ekranu) odpowiada pozycji początkowej myszy (ekranu).
- Jeśli nie, przenosi okno do ekranu, z którego uruchomiono aplikację. W większości przypadków akcja będzie na (bardzo) wczesnym etapie istnienia okna, więc nawet tego nie zauważysz.
Problem / rozwiązanie
Jest jedna wada: jeśli zastąpisz główne polecenie .desktop
pliku poleceniem wywołania tego skryptu, kliknięcie prawym przyciskiem myszy „otwórz za pomocą” nie będzie działać poprawnie. W przypadku przeglądarki internetowej takiej jak Google Chrome nie będzie to zbyt dużym problemem. W przypadku innych aplikacji prostym rozwiązaniem byłoby dodanie opcji otwarcia nowego okna na bieżącym ekranie jako skrótu (patrz dalej poniżej).
Jak używać:
Skrypt korzysta zarówno wmctrl
a xautomation
:
sudo apt-get install xautomation
sudo apt-get install wmctrl
Utwórz katalog, ~/bin
jeśli jeszcze nie istnieje.
Skopiuj skrypt do pustego pliku, zapisz go jako open_oncurrent
(bez rozszerzenia) w~/bin
- Spraw, by był wykonywalny (!)
Skopiuj odpowiedni .desktop
plik z /usr/share/applications
do ~/.local/share/applications
:
cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/google-chrome.desktop
Otwórz lokalną kopię w ~/.local/share/applications
:
gedit ~/.local/share/applications/google-chrome.desktop
Edytuj plik (dwie opcje):
Aby zmienić główne polecenie programu uruchamiającego:
Aby dodać opcję jako skrót (jak na powyższym obrazku):
znajdź linię:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;
zastąp to:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;New window on this screen;
Następnie dodaj następującą sekcję na samym końcu pliku:
[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
Jak korzystać z innych aplikacji:
Podobnie możesz zastosować rozwiązanie do innych aplikacji. Składnia polecenia do użycia w .desktop
pliku jest jak w przykładzie:
Exec=/bin/bash -c "open_oncurrent <command>"
Małe dodatkowe wyjaśnienie, jak radzić sobie z wyjątkami, znajduje się w skrypcie.
Scenariusz
#!/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)