introduzione
Lo script seguente consente di selezionare due finestre e, mentre entrambe le finestre sono aperte, solleverà entrambe le finestre quando l'utente mette a fuoco una delle due. Ad esempio, se si collegano le vedove A e B, la strega con A o B farà alzare entrambi sopra le altre vedove.
Per interrompere lo script è possibile utilizzare killall link_windows.py
nel terminale oppure chiudere e riaprire una delle finestre. È inoltre possibile annullare l'esecuzione premendo il pulsante Chiudi Xin una delle finestre di dialogo popup di selezione della finestra.
Potenziali modifiche:
- più istanze dello script possono essere utilizzate per raggruppare coppie di due finestre. Ad esempio, se abbiamo finestre A, B, C e D, possiamo collegare A e B insieme e collegare C e D insieme.
- più finestre possono essere raggruppate in un'unica finestra. Ad esempio, se collego la finestra da B a A, da C ad A e da D ad A, ciò significa che se passo sempre ad A, posso sollevare tutte e 4 le finestre contemporaneamente.
uso
Esegui lo script come:
python link_windows.py
Lo script è compatibile con Python 3, quindi può anche essere eseguito come
python3 link_windows.py
Esistono due opzioni della riga di comando:
--quiet
oppure -q
, consente di silenziare le finestre della GUI. Con questa opzione puoi semplicemente fare clic con il mouse su due finestre e lo script inizierà a collegarle.
--help
oppure -h
stampa le informazioni sull'utilizzo e sulla descrizione.
L' -h
opzione produce le seguenti informazioni:
$ 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.
Ulteriori informazioni tecniche possono essere visualizzate tramite pydoc ./link_windows.py
, dove ./
indica che è necessario trovarsi nella stessa directory dello script.
Semplice processo di utilizzo per due finestre:
Apparirà un popup che ti chiederà di selezionare una finestra n. 1, premere OKo premere Enter. Il puntatore del mouse si trasformerà in una croce. Fai clic su una delle finestre che desideri collegare.
Apparirà un secondo popup che ti chiederà di selezionare la finestra # 2, premi OKo premi Enter. Ancora una volta, il puntatore del mouse si trasformerà in una croce. Fare clic sull'altra finestra che si desidera collegare. Dopo tale esecuzione avrà inizio.
Ogni volta che focalizzi una delle finestre, lo script solleverà l'altra finestra, ma riporta lo stato attivo su quella originariamente selezionata (nota - con un quarto di secondo di ritardo per le migliori prestazioni), creando così la sensazione che le finestre siano collegate tra loro.
Se si seleziona la stessa finestra entrambe le volte, lo script verrà chiuso. Se in qualsiasi momento fai clic sul pulsante Chiudi della finestra di dialogo popup, lo script verrà chiuso.
Fonte dello script
Disponibile anche come GitHub Gist
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date: August 2nd, 2016
Written for: https://askubuntu.com/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()
Appunti: