Kann ich ein Fenster haben, in dem eine kleine Live-Vorschau eines anderen Arbeitsbereichs angezeigt wird?

29

Ist es möglich, einen Live-Bereich eines Arbeitsbereichs so zu spiegeln, dass er im aktuellen Arbeitsbereich als verschiebbares Fenster sichtbar ist?

Neulich lief auf meinem Ubuntu 16.04-Host eine Windows 10-VM, deren Aktualisierung sehr lange gedauert hat. Ich habe den Fortschritt über Expo ( Super+ S) auf Ubuntu überprüft . Das hat mich zu dem Gedanken gebracht, dass dieses Problem höchstwahrscheinlich bereits gelöst wurde, da Tools wie der Simplescreen-Recorder so konfiguriert werden können, dass nur ein Teil des Bildschirms aufgezeichnet wird. Ich kenne jedoch nicht die richtige Terminologie für meine Google-Suche.

Ich möchte den 300x150-Screenshot unten in Form eines schwebenden Fensters (mit Live-Updates) in der oberen rechten Ecke des aktuellen Arbeitsbereichs sehen.

Bildbeschreibung hier eingeben

AnthonyK
quelle
1
@ Serg hier ein neues Projekt für Sie
Rinzwind
@Rinzwind du musst Serg hassen ... Wir (beide) haben sowas schon mal angeschaut, haben es nicht geschafft.
Jacob Vlijm
1
Diesmal habe ich sogar ein Kopfgeld darauf gezahlt: =) Komme dazu @JacobVlijm
Rinzwind
Wäre eine coole Funktion :) Im VM-Fall hilft es nicht, aber für Terminalanwendungen gibt es eine Lösung: die Verwendung von Konsole. Es gibt zwei nützliche Optionen: "Benachrichtigung bei Aktivität" und "Benachrichtigung bei Stille". Der erste sendet Ihnen eine Benachrichtigung, wenn eine neue Zeile im Terminal angezeigt wird (nützlich, wenn tail -F file | grep patternProtokolle verwendet werden, um vor bestimmten Ereignissen gewarnt zu werden). Der zweite sendet Ihnen eine Benachrichtigung, wenn seit der letzten geschriebenen Zeile etwas Zeit vergangen ist (nützlich, um wissen, wann ein Build beendet ist).
Kik
@ Rinzwind heiliger Mist, es wird funktionieren ...
Jacob Vlijm

Antworten:

26

BEARBEITEN

(Neue Antwort)

GETAN.
Die folgende Antwort ist jetzt in einer polierten Form als Indikator als ppa für Trusty, Xenial, Yakkety und Zesty verfügbar:

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

Der Indikator (einschließlich des Vorschaufensters) hat jetzt nur noch wenig Saft. Zu den Optionen gehören ein Einstellungsfenster, die Einstellung der Fensterrahmengröße / -farbe und der Fenstergröße.

Bildbeschreibung hier eingeben

In der Zwischenzeit fand ich es nützlich, das AU-Fenster im Auge zu behalten. schau ob es irgendwelche nachrichten gibt :)


ALTE ANTWORT

( erstes zweites grobes Konzept)

Minimierte Darstellung eines Fensters in einem anderen Arbeitsbereich

Zu meiner eigenen (großen) Überraschung kann es effektiv durchgeführt werden, sei es mit Betrug und Täuschung; eine aktualisierte Darstellung eines Fensters in einem anderen Arbeitsbereich haben. Nicht zum Ansehen eines Films geeignet, auf jeden Fall gut genug, um ein Fenster an einer anderen Stelle im Auge zu behalten (Beispiel: mein Fernsehkartenfenster):

Wie es in der Praxis funktioniert

  1. Drücken Sie bei geöffnetem Fenster eine Tastenkombination:

    Bildbeschreibung hier eingeben

    (das Fenster wird minimiert)

  2. Wechseln Sie zu einem anderen Arbeitsbereich, drücken Sie die Tastenkombination erneut. Eine kleine Darstellung des Fensters wird angezeigt, die alle 4 Sekunden aktualisiert wird:

    Bildbeschreibung hier eingeben

    Das Fenster wird immer über anderen Fenstern angezeigt. Wie es ist, ist das Fenster 300px (Breite), kann aber auf eine beliebige Größe eingestellt werden.

  3. Drücken Sie zum Beenden (erneut) die Direktaufruftaste. Das kleine Fenster wird geschlossen und Sie gelangen in das Ansichtsfenster des ursprünglichen Fensters, das wieder angezeigt wird.

Die Skripte

  1. Das Kontrollskript

    #!/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. Das Fenster repräsentatiom

    #!/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()

Wie benutzt man

  1. Installieren python3-pil, xdotoolundwmctrl

    sudo apt-get install xdotool wmctrl python3-pil
    
  2. Erstellen Sie das Verzeichnis, falls es noch nicht existiert ~/bin.

  3. Kopiere Skript 1, er steuere Skript, als (genau) showcase_control(keine Endung) ein ~/binund mache es ausführbar .
  4. Kopieren Sie Skript 2, das Minifenster-Skript, als (genau) showmin(keine Erweiterung) ~/binund machen Sie es ausführbar .
  5. Melden Sie sich ab und wieder an und fügen Sie den folgenden Befehl zu einer Verknüpfung Ihrer Wahl hinzu:

    showcase_control
    

    Wählen Sie: Systemeinstellungen> "Tastatur"> "Verknüpfungen"> "Benutzerdefinierte Verknüpfungen". Klicken Sie auf das "+" und fügen Sie den Befehl hinzu:

    showcase_control
    

    und es sollte funktionieren!

    • Drücken Sie die Taste einmal, um das aktuelle Fenster zu öffnen
    • Wechseln Sie in den anderen Arbeitsbereich, in dem Sie das Mini-Fenster haben möchten
    • Drücken Sie erneut, um das Mini-Fenster anzuzeigen
    • Erneut drücken, um zum ursprünglichen Arbeitsbereich zurückzukehren, das ursprüngliche Fenster (automatisch) zu minimieren und das Mini-One zu schließen.

Nachteile?

  • Das derzeitige Setup fügt Ihrem Prozessor einige Arbeit hinzu . Auf meinem (sehr) alten System werden jedoch (im Durchschnitt) ca. Ich rechne mit 4-5%, die ich in keiner Weise bemerkt habe .

    Update: Es hat sich herausgestellt, dass importdie Größe des Bildes in einem Schritt geändert werden kann, zusammen mit dem Abrufen des Fensterbildes. Dies bedeutet eine erhebliche Reduzierung der Prozessorlast. Gleichzeitig ist die Auffrischungszeit kürzer (jetzt 3 Sekunden), immer noch zu geringeren "Kosten".

Erläuterung

  • Mein Ausgangspunkt war die Art und Weise, wie OP erwähnte, dass er die Option nutzen wollte, um ein Fenster in einem anderen Arbeitsbereich im Auge zu behalten und darauf zu warten, dass einer der beiden Schritte abgeschlossen ist.
  • Während buchstäblich genau ein mit (mini) auf einem anderen Arbeitsbereich eines Fensters zu kopieren scheint unmöglich, wir können ein Bild eines bestehenden Fenster mit dem machen import-command, sobald wir die Fenster - ID haben. Dies funktioniert zwar bei minimierten Fenstern oder Fenstern ohne Fokus, es gibt jedoch ein Problem: Das Fenster muss sich im aktuellen Arbeitsbereich befinden .
  • Der Trick besteht dann darin, das Fenster vorübergehend (während das Mini-Fenster verwendet wird) "klebrig" zu machen (praktisch auf allen Arbeitsbereichen verfügbar zu sein) wmctrl, gleichzeitig aber zu minimieren.
  • Da alles automatisch erledigt wird, ist der Unterschied praktisch gleich Null, da auch die Rückkehr zum ursprünglichen Ansichtsfenster, das "nicht kleben" des ursprünglichen Fensters und das Unminimieren desselben, automatisch erledigt wird.

Zusamenfassend:

  1. Einmaliges Drücken der Verknüpfung: Das Zielfenster wird verklebt, aber minimiert
  2. Erneutes Drücken (vermutlich in einem anderen Arbeitsbereich): In der oberen linken Ecke wird eine kleine Miniversion des Fensters angezeigt, die alle vier Sekunden aktualisiert wird.
  3. Erneutes Drücken: Das Mini-Fenster wird geschlossen, der Desktop wechselt zum ursprünglichen Arbeitsbereich des Fensters, das Fenster wird wiederhergestellt, ohne zu kleben und ohne zu verkleinern.

Speziell für VirtualBox

Wenn sich das VBox-Fenster vorne befindet, sind die Ubuntu-Tastenkombinationen deaktiviert (!), Sodass das Kontrollskript auf andere Weise gestartet werden muss. Nachfolgend einige kurze.

Option 1

Ich habe das Kontrollskript bearbeitet. Jetzt nur noch bei VirtualBox:

  • Klicken Sie überall auf dem Desktop, dann drücken Sie Ihre Schnelltaste. Verwenden Sie danach einfach die Tastenkombination, um das Fenster anzuzeigen und zu beenden.

    Erläuterung: Das Steuerungsskript wurde so erstellt, dass es beendet wird, wenn das Fenster vom Typ "desktop" ist, da Sie den Desktop nicht minimieren möchten. Das Skript sucht nun zunächst nach möglicherweise vorhandenen VirtualBox-Fenstern, um darauf abzielen zu können, ob das derzeit aktive Fenster der Desktop ist.

Option 2

  • Kopieren Sie das unten stehende Symbol (Rechtsklick -> Speichern unter) und speichern Sie es unter minwinicon.png

    Bildbeschreibung hier eingeben

  • Kopieren Sie die folgenden Zeilen in eine leere Datei und speichern Sie sie wie minwin.desktopfolgt ~/.local/share/applications:

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

    Sie müssen sich abmelden und wieder anmelden, damit der Launcher den lokalen ~/binPfad "findet" !
    Ziehen Sie das Symbol auf den Launcher, um es zu verwenden.

Die zweite Lösung hat einen wichtigen Nachteil: Nachdem sie vom Launcher aus verwendet wurde, blinkt sie einige Sekunden lang, bis ein Fenster angezeigt wird. Währenddessen hat ein erneutes Klicken keine Auswirkung. Das kann gelöst werden, wie hier beschrieben , aber die Aufnahme in diese Antwort würde es wirklich zu lang machen. Wenn Sie Option zwei verwenden möchten, schauen Sie bitte in den Link.

Jacob Vlijm
quelle
Also, gute alte importkönnen es, während der Gnome-Screenshot es nicht kann. Sehr sehr interessant. Ich bin gespannt, was genau der Unterschied zwischen ihrer Arbeitsweise ist
Sergiy Kolodyazhnyy
@ Serg ja, ich war wirklich überrascht, dachte, es könnte nicht nur mit Küchenwerkzeugen getan werden :)
Jacob Vlijm
1
@ThatGuy arbeitet daran :)
Jacob Vlijm
1
@jymbob Danke für den Kommentar! Sie sind zweifellos im System, aber die Frage ist, ob sie von außen verfügbar sind. Wenn die Entwickler in keiner Weise eine CLI-Option oder eine API bereitstellen, wäre es eine völlig andere Aufgabe, in den Code einzudringen. Ich hätte aber gerne die Option.
Jacob Vlijm
1
@JacobVlijm Fairer Punkt. Möglicherweise mehr Infos hier stackoverflow.com/questions/18595951/… aber weit über meinem Kompetenzniveau!
Symbob
1

Etwas, das übertrieben scheint, aber für diesen Zweck völlig funktioniert, ist Open Broadcaster . Klicken Sie im Listenfeld "Quellen" auf das Pluszeichen, wählen Sie "Fenstererfassung" und befolgen Sie die Anweisungen, um das gewünschte Fenster auszuwählen. benutze einfach die Vorschau. Es ist für verfügbar ziemlich jedes Betriebssystem , mit Anweisungen für Ubuntu hier , die ich weiter unten kopiert habe.

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

Wenn Sie möchten, können Sie in das Menü "Ansicht" wechseln und alle Elemente der Benutzeroberfläche ausblenden.

golvok
quelle