J'ai deux fenêtres, A et B. Est-il possible de lier deux fenêtres ensemble, de sorte que le passage à A soulève également B, ou que le passage à B soulève également A?
Je comprends que l'utilisation de plusieurs espaces de travail est une option alternative, mais je me demandais si cela était également possible?
Le script suivant permet de sélectionner deux fenêtres. Lorsque les deux fenêtres sont ouvertes, il soulève les deux fenêtres lorsque l'utilisateur fait la mise au point. Par exemple, si l’on lie les veuves A et B, le fait de passer à A ou B fera augmenter les deux au-dessus des autres veuves.
Pour arrêter le script, vous pouvez utiliser killall link_windows.py
dans un terminal, ou fermer et rouvrir une des fenêtres. Vous pouvez également annuler l'exécution en appuyant sur le bouton de fermeture X dans l’une des boîtes de dialogue contextuelles de sélection de fenêtre.
Réglages potentiels:
Exécutez le script en tant que:
python link_windows.py
Le script est compatible avec Python 3, de sorte qu'il peut également s'exécuter en tant que
python3 link_windows.py
Il existe deux options de ligne de commande:
--quiet
ou -q
, permet de désactiver les fenêtres de l'interface graphique. Avec cette option, vous pouvez simplement cliquer avec la souris sur deux fenêtres et le script commencera à les lier.--help
ou -h
imprime les informations d'utilisation et de description.L'option -h
fournit les informations suivantes:
$ 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.
Des informations techniques supplémentaires peuvent être consultées via pydoc ./link_windows.py
, où ./
signifie que vous devez vous trouver dans le même répertoire que le script.
Processus d'utilisation simple pour deux fenêtres:
Une fenêtre contextuelle vous demandant de sélectionner une fenêtre n ° 1 apparaît. Appuyez sur OK ou frapper Enter. Le pointeur de la souris se transformera en croix. Cliquez sur l'une des fenêtres que vous souhaitez lier.
Une seconde fenêtre apparaît vous demandant de sélectionner la fenêtre 2, appuyez sur OK ou frapper Enter. Encore une fois, le pointeur de la souris se transformera en croix.Cliquez sur l’autre fenêtre à lier. Après cette exécution va commencer.
Chaque fois que vous focalisez l'une ou l'autre fenêtre, le script soulève l'autre fenêtre, mais rétablit le focus sur celle sélectionnée à l'origine (remarque - avec un délai d'un quart de seconde pour des performances optimales), ce qui donne l'impression que les fenêtres sont liées.
Si vous sélectionnez la même fenêtre à deux reprises, le script se ferme. Si, à tout moment, vous cliquez sur le bouton de fermeture de la boîte de dialogue contextuelle, le script se ferme.
Egalement disponible en tant que 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 __== "__main__":
main()
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
Elles peuvent être ignorées.La solution ci-dessous vous permettra de choisir toute combinaison de deux, trois fenêtres ou plus à combiner et à afficher en une avec un raccourci clavier.
Le script fonctionne avec trois arguments:
add
ajouter la fenêtre active au groupe
raise
élever le groupe
clear
pour effacer le groupe, prêt à définir un nouveau groupe
#!/usr/bin/env python3
import sys
import os
import subprocess
wlist = os.path.join(os.environ["HOME"], ".windowlist")
arg = sys.argv[1]
if arg == "add":
active = subprocess.check_output([
"xdotool", "getactivewindow"
]).decode("utf-8").strip()
try:
currlist = open(wlist).read()
except FileNotFoundError:
currlist = []
if not active in currlist:
open(wlist, "a").write(active + "\n")
Elif arg == "raise":
group = [w.strip() for w in open(wlist).readlines()]
[subprocess.call(["wmctrl", "-ia", w]) for w in group]
Elif arg == "clear":
os.remove(wlist)
Le script a besoin de wmctrl
et xdotool
:
Sudo apt-get install wmctrl xdotool
groupwindows.py
Testez le script: ouvrez deux fenêtres de terminal, lancez la commande:
python3 /absolute/path/to/groupwindows.py add
dans les deux. Couvrez-les avec d'autres fenêtres (ou minimisez-les). Ouvrez une troisième fenêtre de terminal, lancez la commande:
python3 /absolute/path/to/groupwindows.py raise
Les deux premières fenêtres seront levées comme une seule.
Si tout fonctionne correctement, créez trois touches de raccourci personnalisées: Choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez les commandes ci-dessous à trois raccourcis distincts:
sur mon système, j'ai utilisé:
Alt+A, en exécutant la commande:
python3 /absolute/path/to/groupwindows.py add
... pour ajouter une fenêtre au groupe.
Alt+R, en exécutant la commande:
python3 /absolute/path/to/groupwindows.py raise
... pour élever le groupe.
Alt+C, en exécutant la commande:
python3 /absolute/path/to/groupwindows.py clear
... pour effacer le groupe
Le script fonctionne tout simplement:
add
, le script enregistre/ajoute l'identifiant de fenêtre de la fenêtre active dans un fichier caché ~/.windowlist
Lorsqu'il est exécuté avec l'argument raise
, le script lit le fichier, soulève les fenêtres de la liste à l'aide de la commande suivante:
wmctrl -ia <window_id>
clear
, le script supprime le fichier caché ~/.windowlist
.Comme mentionné, le script ci-dessus permet d'ajouter des fenêtres à tout moment aux fenêtres groupées. La version ci-dessous autorise également supprimer n'importe laquelle des fenêtres (à tout moment) de la liste groupée:
#!/usr/bin/env python3
import sys
import os
import subprocess
wlist = os.path.join(os.environ["HOME"], ".windowlist")
arg = sys.argv[1]
# add windows to the group
if arg == "add":
active = subprocess.check_output([
"xdotool", "getactivewindow"
]).decode("utf-8").strip()
try:
currlist = open(wlist).read()
except FileNotFoundError:
currlist = []
if not active in currlist:
open(wlist, "a").write(active + "\n")
# delete window from the group
if arg == "delete":
try:
currlist = [w.strip() for w in open(wlist).readlines()]
except FileNotFoundError:
pass
else:
currlist.remove(subprocess.check_output([
"xdotool", "getactivewindow"]).decode("utf-8").strip())
open(wlist, "w").write("\n".join(currlist)+"\n")
# raise the grouped windows
Elif arg == "raise":
group = [w.strip() for w in open(wlist).readlines()]
[subprocess.call(["wmctrl", "-ia", w]) for w in group]
# clear the grouped window list
Elif arg == "clear":
os.remove(wlist)
L'argument supplémentaire pour exécuter le script est delete
, donc:
python3 /absolute/path/to/groupwindows.py delete
supprime la fenêtre active des fenêtres groupées. Pour exécuter cette commande, sur mon système, je mets Alt+D comme raccourci.