Giới thiệu
Kịch bản sau đây cho phép chọn hai cửa sổ và trong khi cả hai cửa sổ đều mở, nó sẽ nâng cả hai cửa sổ khi người dùng tập trung vào một trong hai cửa sổ. Chẳng hạn, nếu một liên kết góa phụ A và B, phù hợp với A hoặc B sẽ khiến cả hai nâng cao hơn các góa phụ khác.
Để dừng tập lệnh, bạn có thể sử dụng killall link_windows.py
trong thiết bị đầu cuối hoặc đóng và mở lại một trong các cửa sổ. Bạn cũng có thể hủy thực thi bằng cách nhấn nút đóng Xtrên một trong các hộp thoại bật lên chọn cửa sổ.
Điều chỉnh tiềm năng:
- nhiều phiên bản của tập lệnh có thể được sử dụng để nhóm các cặp của hai cửa sổ. Ví dụ: nếu chúng ta có các cửa sổ A, B, C và D, chúng ta có thể liên kết A và B với nhau và liên kết C và D với nhau.
- nhiều cửa sổ có thể được nhóm lại dưới một cửa sổ duy nhất. Ví dụ: nếu tôi liên kết cửa sổ B với A, C với A và D với A, điều đó có nghĩa là nếu tôi luôn chuyển sang A, tôi có thể nâng cả 4 cửa sổ cùng một lúc.
Sử dụng
Chạy tập lệnh dưới dạng:
python link_windows.py
Kịch bản tương thích với Python 3, vì vậy nó cũng có thể chạy như
python3 link_windows.py
Có hai tùy chọn dòng lệnh:
--quiet
hoặc -q
, cho phép tắt các cửa sổ GUI. Với tùy chọn này, bạn có thể chỉ cần nhấp chuột vào bất kỳ hai cửa sổ nào và tập lệnh sẽ bắt đầu liên kết các cửa sổ đó.
--help
hoặc -h
, in thông tin sử dụng và mô tả.
Các -h
tùy chọn tạo ra các thông tin sau:
$ python3 link_windows.py -h
usage: link_windows.py [-h] [--quiet]
Linker for two X11 windows.Allows raising two user selected windows together
optional arguments:
-h, --help show this help message and exit
-q, --quiet Blocks GUI dialogs.
Thông tin kỹ thuật bổ sung có thể được xem qua pydoc ./link_windows.py
, trong đó ./
biểu thị rằng bạn phải ở cùng thư mục với tập lệnh.
Quy trình sử dụng đơn giản cho hai cửa sổ:
Một cửa sổ bật lên sẽ xuất hiện yêu cầu bạn chọn cửa sổ số 1, nhấn OKhoặc nhấn Enter. Con trỏ chuột sẽ chuyển sang hình chữ thập. Nhấp vào một trong những cửa sổ bạn muốn liên kết.
Một cửa sổ bật lên thứ hai sẽ xuất hiện yêu cầu bạn chọn cửa sổ số 2, nhấn OKhoặc nhấn Enter. Một lần nữa, con trỏ chuột sẽ biến thành hình chữ thập. Bấm vào cửa sổ khác mà bạn muốn liên kết. Sau đó thực hiện sẽ bắt đầu.
Bất cứ khi nào bạn tập trung vào một trong hai cửa sổ, tập lệnh sẽ nâng cửa sổ khác lên, nhưng trả lại tiêu điểm cho cửa sổ được chọn ban đầu (lưu ý - với một phần tư độ trễ thứ hai để có hiệu suất tốt nhất), do đó tạo cảm giác các cửa sổ được liên kết với nhau.
Nếu bạn chọn cùng một cửa sổ cả hai lần, tập lệnh sẽ thoát. Nếu bất cứ lúc nào bạn nhấp vào nút đóng của hộp thoại bật lên, tập lệnh sẽ thoát.
Nguồn kịch bản
Cũng có sẵn như GitHub Gist
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date: August 2nd, 2016
Written for: /ubuntu//q/805515/295286
Tested on Ubuntu 16.04 LTS
"""
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gtk
import time
import subprocess
import sys
import argparse
def run_cmd(cmdlist):
""" Reusable function for running shell commands"""
try:
stdout = subprocess.check_output(cmdlist)
except subprocess.CalledProcessError:
sys.exit(1)
else:
if stdout:
return stdout
def focus_windows_in_order(first, second, scr):
"""Raise two user-defined windows above others.
Takes two XID integers and screen object.
Window with first XID will have the focus"""
first_obj = None
second_obj = None
for window in scr.get_window_stack():
if window.get_xid() == first:
first_obj = window
if window.get_xid() == second:
second_obj = window
# When this function is called first_obj is alread
# raised. Therefore we must raise second one, and switch
# back to first
second_obj.focus(int(time.time()))
second_obj.get_update_area()
# time.sleep(0.25)
first_obj.focus(int(time.time()))
first_obj.get_update_area()
def get_user_window():
"""Select two windows via mouse. Returns integer value of window's id"""
window_id = None
while not window_id:
for line in run_cmd(['xwininfo', '-int']).decode().split('\n'):
if 'Window id:' in line:
window_id = line.split()[3]
return int(window_id)
def main():
""" Main function. This is where polling for window stack is done"""
# Parse command line arguments
arg_parser = argparse.ArgumentParser(
description="""Linker for two X11 windows.Allows raising """ +
"""two user selected windows together""")
arg_parser.add_argument(
'-q','--quiet', action='store_true',
help='Blocks GUI dialogs.',
required=False)
args = arg_parser.parse_args()
# Obtain list of two user windows
user_windows = [None, None]
if not args.quiet:
run_cmd(['zenity', '--info', '--text="select first window"'])
user_windows[0] = get_user_window()
if not args.quiet:
run_cmd(['zenity', '--info', '--text="select second window"'])
user_windows[1] = get_user_window()
if user_windows[0] == user_windows[1]:
run_cmd(
['zenity', '--error', '--text="Same window selected. Exiting"'])
sys.exit(1)
screen = Gdk.Screen.get_default()
flag = False
# begin watching for changes in window stack
while True:
window_stack = [window.get_xid()
for window in screen.get_window_stack()]
if user_windows[0] in window_stack and user_windows[1] in window_stack:
active_xid = screen.get_active_window().get_xid()
if active_xid not in user_windows:
flag = True
if flag and active_xid == user_windows[0]:
focus_windows_in_order(
user_windows[0], user_windows[1], screen)
flag = False
elif flag and active_xid == user_windows[1]:
focus_windows_in_order(
user_windows[1], user_windows[0], screen)
flag = False
else:
break
time.sleep(0.15)
if __name__ == "__main__":
main()
Ghi chú