web-dev-qa-db-fra.com

Puis-je avoir une fenêtre montrant un petit aperçu en direct d'un autre espace de travail?

Est-il possible de refléter une section active d'un espace de travail afin qu'elle soit visible dans l'espace de travail actuel en tant que fenêtre pouvant être déplacée?

L'autre jour, un ordinateur fonctionnant sous Windows 10 VM s'exécutant sur mon hôte Ubuntu 16.04 était très long à mettre à jour. Je surveillais ses progrès via Expo (Super+S) sur Ubuntu. Cela m'a fait penser que ce problème avait probablement déjà été résolu, car des outils tels que simplescreenrecorder peuvent être configurés pour enregistrer uniquement une partie de l'écran. Cependant, je ne connais pas la terminologie appropriée à utiliser pour mes recherches sur Google.

J'aimerais voir la capture d'écran 300x150 ci-dessous sous la forme d'une fenêtre flottante (avec mises à jour en direct) dans le coin supérieur droit de n'importe quel espace de travail en cours.

enter image description here

28
AnthonyK

MODIFIER

(nouvelle réponse)

FAIT.
La réponse ci-dessous est maintenant disponible sous forme polie, à titre d'indicateur, en tant que PPA pour Trusty, Xenial, Yakkety et Zesty:

Sudo apt-add-repository ppa:vlijm/windowspy
Sudo apt-get update
Sudo apt-get install windowspy

L’indicateur (y compris la fenêtre d’aperçu) est maintenant bien vide. Les options incluent une fenêtre de paramètres, une taille/couleur de bordure de fenêtre, une taille de fenêtre.

enter image description here

En attendant, j'ai trouvé utile de garder un œil sur la fenêtre de l'UA; voir s'il y a des messages :)


ANCIENNE RÉPONSE

(premier deuxième concept approximatif)

Avoir une représentation minimisée d'une fenêtre sur un autre espace de travail

À ma (grande) surprise, cela peut être efficacement , que ce soit avec de la tromperie et de la duperie; avoir une représentation mise à jour d'une fenêtre sur un autre espace de travail. Pas apte à regarder un film, mais assez bien pour garder un œil sur une fenêtre ailleurs (exemple: la fenêtre de ma carte tv):

Comment ça marche en pratique

  1. Avec la fenêtre en face, appuyez sur une touche de raccourci:

    enter image description here

    (la fenêtre minimisera)

  2. Déplacez-vous vers un autre espace de travail, appuyez à nouveau sur la touche de raccourci, une petite représentation de la fenêtre apparaîtra, mise à jour toutes les 4 secondes:

    enter image description here

    La fenêtre apparaît toujours au-dessus des autres fenêtres. Dans l’état actuel, la fenêtre mesure 300 pixels (largeur), mais peut être réglée sur n’importe quelle taille.

  3. Pour y mettre fin, appuyez à nouveau sur la touche de raccourci. La petite fenêtre se fermera, vous passerez à la fenêtre de la fenêtre d'origine qui apparaîtra à nouveau, sans être minimisée.

Les scripts

  1. Le script de contrôle

    #!/usr/bin/env python3
    import subprocess
    import os
    import sys
    import time
    
    # paths
    imagepath = os.path.join(os.environ["HOME"], ".showcase")
    wfile = os.path.join(imagepath, "currentwindow")
    vpfile = os.path.join(imagepath, "last_vp")
    # setup path
    if not os.path.exists(imagepath):
        os.mkdir(imagepath)
    
    def get(command):
        try:
            return subprocess.check_output(command).decode("utf-8").strip()
        except subprocess.CalledProcessError:
            pass
    
    def get_vp():
        open(vpfile, "wt").write(get(["wmctrl", "-d"]).split()[5])
    
    def run(command):
        subprocess.Popen(command)
    
    def convert_tohex(widxd):
        return widxd[:2]+((10-len(widxd))*"0")+widxd[2:]
    
    def check_windowtype(wid):
        check = get(["xprop", "-id", wid])
        return not any([s in check for s in [
            "_NET_WM_WINDOW_TYPE_DOCK",
            "_NET_WM_WINDOW_TYPE_DESKTOP"]])
    
    def edit_winprops(wid, convert=True):
        run(["xdotool", "windowminimize", wid])
        if convert:
            widxd = convert_tohex(hex(int(wid)))
        else:
            widxd = wid
        run(["wmctrl", "-i", "-r", widxd, "-b", "add,sticky"])
        get_vp()
        open(os.path.join(imagepath, "currentwindow"), "wt").write(widxd)
    
    def initiate_min():
        # if not, minmize window, write the file
        wid = get(["xdotool", "getactivewindow"])
        if check_windowtype(wid):
            edit_winprops(wid)
        else:
            pidinfo = [l.split() for l in wlist.splitlines()]
            match = [l for l in pidinfo if all([
                get(["ps", "-p", l[2], "-o", "comm="]) == "VirtualBox",
                not "Manager" in l])]
            if match:
                edit_winprops(match[0][0], convert=False)
    
    # windowlist
    wlist = get(["wmctrl", "-lp"])
    
    if "Window preview" in wlist:
        # kill the miniwindow
        pid = get(["pgrep", "-f", "showmin"])
        run(["kill", pid])
        window = open(wfile).read().strip()
        viewport = open(vpfile).read().strip()
        run(["wmctrl", "-o", viewport])
        time.sleep(0.3)
        run(["wmctrl", "-i", "-r", window, "-b", "remove,sticky"])
        run(["wmctrl", "-ia", window])
        os.remove(wfile)
    
    else:
        # check if windowfile exists
        wfileexists = os.path.exists(wfile)
        if wfileexists:
            # if file exists, try to run miniwindow
            window = open(wfile).read().strip()
            if window in wlist:
                # if the window exists, run!
                run(["showmin", window])
            else:
                # if not, minmize window, write the file
                initiate_min()
        else:
            # if not, minmize window, write the file
            initiate_min()
    
  2. La représentation de la fenêtre

    #!/usr/bin/env python3
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk, GObject
    from PIL import Image
    import os
    import subprocess
    import time
    from threading import Thread
    import sys
    
    wid = sys.argv[1]
    xsize = 300
    
    imagepath = os.path.join(os.environ["HOME"], ".showcase")
    if not os.path.exists(imagepath):
        os.mkdir(imagepath)
    img_in = os.path.join(imagepath, "image.png")
    resized = os.path.join(imagepath, "resized.png")
    
    def get_img():
        subprocess.Popen([
            "import", "-window", wid, "-resize", str(xsize),  resized
            ])
    
    get_img()
    
    class Splash(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="Window preview")
            maingrid = Gtk.Grid()
            self.add(maingrid)
            self.image = Gtk.Image()
            # set the path to the image below
            self.resized = resized
            self.image.set_from_file(self.resized)
            maingrid.attach(self.image, 0, 0, 1, 1)
            maingrid.set_border_width(3)
            self.update = Thread(target=self.update_preview)
            self.update.setDaemon(True)
            self.update.start()
    
        def update_preview(self):
            while True:
                get_img()
                time.sleep(3)
                GObject.idle_add(
                    self.image.set_from_file, self.resized,
                    priority=GObject.PRIORITY_DEFAULT
                    )
    
    def miniwindow():
        window = Splash()
        window.set_decorated(False)
        window.set_resizable(False)
        window.set_keep_above(True)
        window.set_wmclass("ShowCase", "showcase")
        window.connect("destroy", Gtk.main_quit)
        GObject.threads_init()
        window.show_all()
        window.move(70, 50)
        Gtk.main()
    
    miniwindow()
    

Comment utiliser

  1. Installez python3-pil, xdotool et wmctrl

    Sudo apt-get install xdotool wmctrl python3-pil
    
  2. Créez, s'il n'existe pas encore, le répertoire ~/bin.

  3. Copiez le script 1, le script de contrôle, comme (exactement) showcase_control (pas d’extension) dans ~/bin, et le rendre exécutable .
  4. Copiez le script 2, le script de mini-fenêtre, comme (exactement) showmin (aucune extension) dans ~/bin, et le rendre exécutable .
  5. Déconnectez-vous et reconnectez-vous, puis ajoutez la commande suivante à un raccourci de votre choix:

    showcase_control
    

    Choisissez: Paramètres système> "Clavier"> "Raccourcis"> "Raccourcis personnalisés". Cliquez sur le "+" et ajoutez la commande:

    showcase_control
    

    et ça devrait marcher!

    • Appuyez une fois sur la touche pour saisir la fenêtre en cours
    • déplacez-vous vers l'autre espace de travail où vous souhaitez que la mini-fenêtre
    • Appuyez à nouveau pour afficher la mini-fenêtre
    • Appuyez à nouveau pour revenir à l'espace de travail d'origine, dé-réduisez (automatiquement) la fenêtre d'origine et fermez la mini-fenêtre.

Inconvénients?

  • La configuration, telle qu’elle est actuellement, ajoute un travail à votre processeur. Sur mon (très) ancien système cependant, il ajoute (en moyenne) appr. 4-5% je pense, ce que je n'ai pas remarqué de manière .

    Mise à jour: Il s'avère que import peut redimensionner l'image en une étape, avec pour extraire l'image de la fenêtre. . Cela signifie une réduction substantielle de la charge du processeur. Dans le même temps, le temps de rafraîchissement est plus court (3 secondes maintenant), toujours à des "coûts" inférieurs.

Explication

  • Mon point de départ était la façon dont OP a indiqué qu'il souhaitait utiliser l'option de garder un œil sur la fenêtre d'un autre espace de travail, en attendant que quelque chose se termine.
  • Alors que littéralement , avoir une (mini) copie exacte d'une fenêtre sur un autre espace de travail semble impossible, nous pouvons créer l'image d'un existant window avec la commande import, une fois que nous avons l'identifiant de la fenêtre. Bien que cela fonctionne à la fois sur des fenêtres réduites ou sur des fenêtres sans focus, il existe toutefois un problème: la fenêtre doit être sur l'espace de travail actuel .
  • L'astuce consiste alors temporairement (pendant que la mini-fenêtre est utilisée) à rendre la fenêtre "collante" (être virtuellement disponible sur tous les espaces de travail) avec wmctrl, mais minimisée en même temps.
  • Puisque tout est fait automatiquement, la différence est nulle, puisqu'un retour à la fenêtre initiale, "décolle" la fenêtre d'origine et la minimise, est fait automatiquement.

En bref:

  1. En appuyant une fois sur le raccourci: la fenêtre ciblée devient collante, mais minimisée
  2. Appuyez à nouveau dessus (probablement sur un autre espace de travail): une petite mini-version de la fenêtre apparaît dans le coin supérieur gauche, mise à jour une fois toutes les quatre secondes.
  3. En appuyant à nouveau: la mini-fenêtre est fermée, le bureau se déplace vers le premier espace de travail de la fenêtre, la fenêtre est restaurée de manière non collante et non minimisée.

Spécifiquement pour VirtualBox

Lorsque la fenêtre de la VBox est au premier plan, il s'avère que les touches de raccourci Ubuntu sont désactivées (!). Le script de contrôle doit donc être lancé d'une autre manière. Ci-dessous quelques brèves.

Option 1

J'ai édité le script de contrôle. Maintenant seulement dans le cas de VirtualBox:

  • Cliquez sur n'importe où sur le bureau, puis appuyez sur la touche de raccourci . Ensuite, utilisez simplement le raccourci clavier pour afficher la fenêtre et quitter.

    Explication: Le script de contrôle a été conçu pour se fermer si la fenêtre était de type "bureau", car vous ne voudriez pas réduire le bureau. Désormais, le script recherche d’abord les fenêtres VirtualBox existantes, à cibler, si la fenêtre actuellement active est le bureau.

Option 2

  • Copiez l'icône ci-dessous (clic droit -> enregistrer sous), enregistrez-la sous le nom minwinicon.png

    enter image description here

  • Copiez les lignes ci-dessous dans un fichier vide, enregistrez-le sous le nom minwin.desktop in ~/.local/share/applications:

    [Desktop Entry]
    Type=Application
    Name=Window Spy
    Exec=showcase_control 
    Icon=/path/to/minwinicon.png
    StartupNotify=false
    

    Vous devez vous déconnecter puis vous reconnecter pour que le programme de lancement lance "le chemin" du chemin ~/bin local!
    Faites glisser l’icône sur le lanceur pour l’utiliser.

La deuxième solution présente un inconvénient important: après l’avoir utilisée depuis le lanceur, elle continue de clignoter pendant quelques secondes, en attendant l’affichage d’une fenêtre. Pendant ce temps, cliquer à nouveau n'aura aucun effet. Que puisse être résolu, comme décrit ici , mais l'inclure dans cette réponse le rendrait vraiment trop long. Si vous souhaitez utiliser la deuxième option, veuillez consulter le lien.

25
Jacob Vlijm