Chuyển hướng lệnh để chạy ứng dụng
Hầu hết các ứng dụng mở cửa sổ của chúng trên màn hình mà chúng được khởi tạo (từ Dash hoặc trình khởi chạy). Tuy nhiên, một số ứng dụng thì không, nhưng chúng có thể bị ép buộc, bằng cách chuyển hướng lệnh để chạy ứng dụng thông qua đoạn script bên dưới. Để làm điều đó, bạn sẽ cần chỉnh sửa .desktop
tệp tương ứng (launcher).
Việc thiết lập có vẻ hơi phức tạp, nhưng nếu quy trình được tuân theo ("Cách sử dụng"), thì nó không quá khó khăn.
Làm thế nào nó hoạt động
- Tập lệnh đọc vị trí chuột tại thời điểm bạn nhấp vào trình khởi chạy hoặc chọn ứng dụng từ Dash và xác định màn hình nào (trái / phải).
- Thỉnh thoảng, nó chờ cửa sổ mới xuất hiện, thuộc sở hữu của ứng dụng (pid) mà bạn đã bắt đầu.
- Khi cửa sổ xuất hiện, nó sẽ kiểm tra xem vị trí cửa sổ (screen-) có khớp với vị trí ban đầu của chuột (screen-) không.
- Nếu không, nó sẽ di chuyển cửa sổ đến màn hình mà bạn đã khởi động ứng dụng từ đó. Trong hầu hết các trường hợp, hành động sẽ ở giai đoạn đầu (rất) của sự tồn tại của cửa sổ, do đó bạn thậm chí sẽ không chú ý đến nó.
Vấn đề / giải pháp
Có một nhược điểm: nếu bạn thay thế lệnh chính.desktop
của tệp bằng lệnh gọi tập lệnh này, nhấp chuột phải "mở bằng" sẽ không hoạt động chính xác. Trong trường hợp một webbrowser như Google Chrome, đó sẽ không phải là vấn đề quá lớn. Với các ứng dụng khác, một giải pháp đơn giản sẽ là thêm tùy chọn mở cửa sổ mới trên màn hình hiện tại dưới dạng phím tắt (xem thêm bên dưới).
Cách sử dụng:
Kịch bản sử dụng cả hai wmctrl
và xautomation
:
sudo apt-get install xautomation
sudo apt-get install wmctrl
Tạo một thư mục ~/bin
nếu nó chưa tồn tại.
Sao chép tập lệnh vào một tệp trống, lưu nó dưới dạng open_oncurrent
(không có phần mở rộng) trong~/bin
- Làm cho nó thực thi (!)
Sao chép .desktop
tệp tương ứng từ /usr/share/applications
sang ~/.local/share/applications
:
cp /usr/share/applications/google-chrome.desktop ~/.local/share/applications/google-chrome.desktop
Mở bản sao cục bộ trong ~/.local/share/applications
:
gedit ~/.local/share/applications/google-chrome.desktop
Chỉnh sửa tệp (hai tùy chọn):
Để thay đổi lệnh chính của launcher:
Để thêm tùy chọn dưới dạng phím tắt (như trong hình trên):
tìm dòng:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;
thay thế nó bằng:
X-Ayatana-Desktop-Shortcuts=NewWindow;NewIncognito;New window on this screen;
Sau đó thêm phần sau vào cuối tập tin:
[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
Cách sử dụng với các ứng dụng khác:
Tương tự, bạn có thể áp dụng giải pháp cho các ứng dụng khác. Cú pháp của lệnh sử dụng trong .desktop
tệp như ví dụ:
Exec=/bin/bash -c "open_oncurrent <command>"
Một lời giải thích bổ sung nhỏ về cách xử lý các trường hợp ngoại lệ có trong kịch bản.
Kịch bản
#!/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)