pengantar
Script berikut memungkinkan memilih dua jendela, dan sementara kedua jendela terbuka, itu akan menaikkan kedua jendela ketika pengguna memfokuskan keduanya. Misalnya, jika seseorang menautkan janda A dan B, mempesonakan ke A atau B akan membuat keduanya naik di atas janda lainnya.
Untuk menghentikan skrip yang dapat Anda gunakan killall link_windows.py
di terminal, atau tutup dan buka kembali salah satu jendela. Anda juga dapat membatalkan eksekusi dengan menekan tombol tutup Xpada salah satu dialog sembulan pilihan jendela.
Potensi tweak:
- beberapa contoh skrip dapat digunakan untuk mengelompokkan pasangan dua jendela. Misalnya, jika kita memiliki windows A, B, C, dan D kita dapat menghubungkan A dan B bersama-sama, dan menghubungkan C dan D bersama-sama.
- beberapa jendela dapat dikelompokkan dalam satu jendela tunggal. Misalnya, jika saya menautkan jendela B ke A, C ke A, dan D ke A, itu berarti jika saya selalu beralih ke A, saya dapat menaikkan semua 4 jendela secara bersamaan.
Pemakaian
Jalankan skrip sebagai:
python link_windows.py
Script ini kompatibel dengan Python 3, sehingga dapat juga dijalankan sebagai
python3 link_windows.py
Ada dua opsi baris perintah:
--quiet
atau -q
, memungkinkan membungkam jendela GUI. Dengan opsi ini Anda cukup mengklik dengan mouse di dua jendela apa saja, dan skrip akan mulai menghubungkannya.
--help
atau -h
, mencetak informasi penggunaan dan deskripsi.
The -h
pilihan menghasilkan informasi berikut:
$ 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.
Informasi teknis tambahan dapat dilihat melalui pydoc ./link_windows.py
, di mana ./
menandakan bahwa Anda harus berada di direktori yang sama dengan skrip.
Proses penggunaan sederhana untuk dua jendela:
Munculan akan muncul meminta Anda untuk memilih jendela # 1, tekan OKatau tekan Enter. Pointer mouse akan berubah menjadi tanda silang. Klik salah satu jendela yang ingin Anda tautkan.
Munculan kedua akan muncul meminta Anda untuk memilih jendela # 2, tekan OKatau tekan Enter. Sekali lagi, penunjuk tetikus akan berubah menjadi tanda silang. Klik pada jendela lain yang ingin Anda tautkan. Setelah itu eksekusi akan dimulai.
Setiap kali Anda memfokuskan kedua jendela, skrip akan menaikkan jendela lainnya, tetapi mengembalikan fokus ke jendela yang sebelumnya dipilih (perhatikan - dengan seperempat penundaan kedua untuk kinerja terbaik), sehingga menciptakan kesan bahwa jendela dihubungkan bersama.
Jika Anda memilih jendela yang sama dua kali, skrip akan berhenti. Jika suatu saat Anda mengklik tombol tutup dialog sembulan, skrip akan berhenti.
Sumber skrip
Juga tersedia sebagai 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()
Catatan: