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

29

Est-il possible de mettre en miroir une section active d'un espace de travail afin qu'elle soit visible dans l'espace de travail actuel comme une fenêtre qui peut être déplacée?

L'autre jour, j'avais une machine virtuelle Windows 10 en cours d'exécution sur mon hôte Ubuntu 16.04, ce qui a pris beaucoup de temps pour terminer la mise à jour. J'ai continué à vérifier ses progrès via Expo ( Super+ S) sur Ubuntu. Cela m'a fait penser que ce problème a probablement déjà été résolu, car des outils tels que simplescreenrecorder peuvent être configurés pour n'enregistrer qu'une partie de l'écran. Cependant, je ne connais pas la terminologie appropriée à utiliser pour ma recherche 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 l'espace de travail qui se trouve être actuel.

entrez la description de l'image ici

AnthonyK
la source
1
@serg ici un nouveau projet pour vous
Rinzwind
@Rinzwind vous devez détester Serg ... Nous (les deux) avons déjà regardé quelque chose comme ça, mais nous n'avons pas réussi.
Jacob Vlijm
1
J'ai même mis une prime dessus cette fois: =) allez
@JacobVlijm
Ce serait une fonctionnalité intéressante :) Cela n'aidera pas dans le cas de la VM, mais il existe une solution pour les applications de terminal: utiliser Konsole. Il a deux options utiles: "notifier sur activité" et "notifier sur silence". Le premier vous enverra une notification lorsqu'une nouvelle ligne est affichée dans le terminal (utile lorsque vous utilisez des tail -F file | grep patternjournaux pour être averti de certains événements), le second vous enverra une notification quand il y a un certain temps depuis la dernière ligne écrite (utile pour savoir quand un build est terminé).
kik
@Rinzwind Holy Crap, ça va marcher ...
Jacob Vlijm

Réponses:

26

MODIFIER

(Nouvelle réponse)

TERMINÉ.
La réponse ci-dessous est maintenant disponible sous une forme raffinée, à 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 de prévisualisation) est maintenant bien bas en jus. Les options incluent une fenêtre de paramètres, le réglage de la taille / couleur de la bordure de la fenêtre, la taille de la fenêtre.

entrez la description de l'image ici

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


RÉPONSE ANCIENNE

( 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 fait efficacement , que ce soit avec la ruse et la tromperie; avoir une représentation mise à jour d'une fenêtre sur un autre espace de travail. Pas apte à regarder un film, certainement assez bon pour garder un œil sur une fenêtre ailleurs (exemple: ma fenêtre de carte TV):

Comment ça marche dans la pratique

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

    entrez la description de l'image ici

    (la fenêtre minimisera)

  2. Passez à 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:

    entrez la description de l'image ici

    La fenêtre s'affiche toujours au-dessus des autres fenêtres. En l'état, la fenêtre mesure 300 pixels (largeur), mais peut être définie sur n'importe quelle taille.

  3. Pour y mettre fin, appuyez (à nouveau) sur la touche de raccourci. La petite fenêtre se fermera, vous vous déplacerez vers la fenêtre de la fenêtre d'origine, qui réapparaîtra, non réduite.

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 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. Installer python3-pil, xdotooletwmctrl

    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, il contrôle le script, comme (exactement) showcase_control(sans extension) ~/bin, et rendez-le exécutable .
  4. Copiez le script 2, le script de mini-fenêtre, comme (exactement) showmin(sans extension) dans ~/bin, et rendez-le exécutable .
  5. Déconnectez-vous et reconnectez-vous, puis ajoutez la commande suivante au 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 actuelle
    • passer à l'autre espace de travail où vous souhaitez la mini-fenêtre
    • Appuyez à nouveau pour afficher la mini-fenêtre
    • Appuyez de nouveau pour revenir à l'espace de travail d'origine, (automatiquement) dé-minimiser la fenêtre d'origine et fermer le mini-un.

Inconvénients?

  • La configuration, telle qu'elle est actuellement, ajoute du travail à votre processeur. Cependant, sur mon (très) ancien système, il ajoute (en moyenne) env. 4-5% je compte, que je ne l' ai pas remarqué en aucune façon.

    Mise à jour: Il s'avère que vous importpouvez redimensionner l'image en une seule étape, ainsi que récupérer 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 mentionné qu'il voulait utiliser l'option pour garder un œil sur une fenêtre d'un autre espace de travail, en attendant que quelque chose se termine.
  • Bien que littéralement avoir une exacte (mini) copie d'une fenêtre sur un autre espace de travail semble impossible, nous pouvons faire une image d'une fenêtre existante avec le import-command, une fois que nous avons l'identifiant de la fenêtre. Bien que cela fonctionne sur des fenêtres réduites ou des fenêtres sans focus, il y a cependant 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 en même temps minimisée.
  • La différence puisque tout est fait automatiquement, efficacement est pas, car aussi revenir à la fenêtre initiale, « ONU- » collant la fenêtre d' origine et ONU- la minimiser, se fait automatiquement.

En bref:

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

Spécifiquement pour VirtualBox

Lorsque la fenêtre VBox est devant, il s'avère que les touches de raccourci Ubuntu sont désactivées (!), Donc le script de contrôle doit ê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 n'importe où sur le bureau, puis appuyez sur votre touche de raccourci. Après cela, utilisez simplement la touche de raccourci pour afficher la fenêtre et quitter.

    Explication: Le script de contrôle a été créé pour quitter si la fenêtre était de type "bureau", car vous ne voudriez pas réduire le bureau. Maintenant, le script cherche d'abord les fenêtres VirtualBox éventuellement 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 minwinicon.png

    entrez la description de l'image ici

  • Copiez les lignes ci-dessous dans un fichier vide, enregistrez-le comme minwin.desktopdans ~/.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 et vous reconnecter pour que le lanceur "trouve" le ~/binchemin local !
    Faites glisser l'icône sur le lanceur pour l'utiliser.

La deuxième solution a un inconvénient important: après l'avoir utilisée depuis le lanceur, elle continuera à clignoter pendant quelques secondes, en attendant qu'une fenêtre apparaisse. Pendant ce temps, cliquer à nouveau n'aura aucun effet. Cela peut être résolu, comme décrit ici , mais l'inclure dans cette réponse serait vraiment trop long. Si vous souhaitez utiliser l'option deux, veuillez consulter le lien.

Jacob Vlijm
la source
Donc, le bon vieux importpeut le faire, contrairement à la capture d'écran gnome. Très, très intéressant. Je suis curieux de savoir quelle est exactement la différence entre leur façon de travailler
Sergiy Kolodyazhnyy
@Serg ouais, j'ai été vraiment surpris, je pensais que cela ne pouvait pas être fait avec seulement des ustensiles de cuisine :)
Jacob Vlijm
1
@ThatGuy y travaille :)
Jacob Vlijm
1
@jymbob Merci pour le commentaire! Ils sont sans doute dans le système, mais la question est de savoir s'ils sont disponibles de l'extérieur. Si les développeurs ne fournissent en aucune façon une option cli ou une API, pénétrer dans le code serait un travail d'un ordre complètement différent. J'aurais bien aimé avoir l'option cependant.
Jacob Vlijm
1
@JacobVlijm Fair point. Peut-être plus d'informations ici stackoverflow.com/questions/18595951/… mais bien au-dessus de mon niveau de compétence!
jymbob
1

Quelque chose qui semble exagéré mais qui fonctionne totalement à cet effet est Open Broadcaster . Dans la zone de liste "Sources", cliquez sur le signe plus, sélectionnez "Capture de fenêtre", puis suivez les invites pour sélectionner la fenêtre qui vous intéresse. Inutile de frapper l'enregistrement; utilisez simplement l'aperçu. Il est disponible pour à peu près n'importe quel système d'exploitation , avec des instructions pour Ubuntu ici , que j'ai copiées ci-dessous.

sudo apt-get install ffmpeg
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt-get update
sudo apt-get install obs-studio

Si vous en avez envie, vous pouvez alors aller dans le menu "Affichage" et masquer tous les éléments de l'interface utilisateur.

golvok
la source