Einführung
Das folgende Skript ermöglicht die Auswahl von zwei Fenstern. Während beide Fenster geöffnet sind, werden beide Fenster geöffnet, wenn der Benutzer eines der beiden Fenster fokussiert. Wenn man beispielsweise die Witwen A und B verbindet, werden beide durch Hexen mit A oder B über andere Witwen erhoben.
Um das Skript zu stoppen, können Sie es killall link_windows.py
im Terminal verwenden oder eines der Fenster schließen und erneut öffnen. Sie können die Ausführung auch abbrechen, indem Sie in Xeinem der Popup-Dialogfelder zur Fensterauswahl auf die Schaltfläche "Schließen" klicken.
Mögliche Verbesserungen:
- Mehrere Instanzen des Skripts können verwendet werden, um Paare von zwei Fenstern zu gruppieren. Wenn wir beispielsweise Fenster A, B, C und D haben, können wir A und B miteinander verbinden und C und D miteinander verbinden.
- Mehrere Fenster können unter einem einzigen Fenster zusammengefasst werden. Wenn ich beispielsweise Fenster B mit A, C mit A und D mit A verbinde, bedeutet dies, dass ich alle 4 Fenster gleichzeitig öffnen kann, wenn ich immer zu A wechsle.
Verwendung
Führen Sie das Skript wie folgt aus:
python link_windows.py
Das Skript ist mit Python 3 kompatibel und kann daher auch als ausgeführt werden
python3 link_windows.py
Es gibt zwei Befehlszeilenoptionen:
--quiet
oder -q
ermöglicht das Stummschalten der GUI-Fenster. Mit dieser Option können Sie einfach mit der Maus auf zwei beliebige Fenster klicken, und das Skript beginnt, diese zu verknüpfen.
--help
oder -h
druckt die Verwendungs- und Beschreibungsinformationen.
Die -h
Option erzeugt die folgenden Informationen:
$ 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.
Zusätzliche technische Informationen können über angezeigt werden pydoc ./link_windows.py
. Dies ./
bedeutet, dass Sie sich im selben Verzeichnis wie das Skript befinden müssen.
Einfacher Verwendungsprozess für zwei Fenster:
Ein Popup wird angezeigt, in dem Sie aufgefordert werden, ein Fenster Nr. 1 auszuwählen, zu drücken OKoder zu drücken Enter. Der Mauszeiger wird zu einem Kreuz. Klicken Sie auf eines der Fenster, die Sie verknüpfen möchten.
Ein zweites Popup wird angezeigt, in dem Sie aufgefordert werden, Fenster 2 auszuwählen, zu drücken OKoder zu drücken Enter. Der Mauszeiger wird wieder zu einem Kreuz. Klicken Sie auf das andere Fenster, das Sie verknüpfen möchten. Danach beginnt die Ausführung.
Wenn Sie eines der beiden Fenster fokussieren, hebt das Skript das andere Fenster an, stellt jedoch den Fokus wieder auf das ursprünglich ausgewählte (Hinweis - mit einer Verzögerung von einer Viertelsekunde für beste Leistung), wodurch das Gefühl entsteht, dass Fenster miteinander verbunden sind.
Wenn Sie beide Male dasselbe Fenster auswählen, wird das Skript beendet. Wenn Sie zu irgendeinem Zeitpunkt auf die Schaltfläche zum Schließen des Popup-Dialogfelds klicken, wird das Skript beendet.
Skriptquelle
Auch als GitHub Gist erhältlich
#!/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()
Anmerkungen: