我可以有一个窗口显示另一个工作区的小型实时预览吗?

我可以有一个窗口显示另一个工作区的小型实时预览吗?

是否可以镜像一个工作区的实际部分,以便它在当前工作区中可见为可移动的窗口?

前几天,我在 Ubuntu 16.04 主机上运行了一个 Windows 10 VM,它花了很长时间才完成更新。我通过 Ubuntu 上的 Expo ( Super+ S) 不断检查其进度。这让我想到这个问题很可能已经解决了,因为可以将 simplescreenrecorder 等工具配置为仅录制屏幕的一部分。但是,我不知道在 Google 搜索中使用什么术语比较合适。

我希望以浮动窗口(带有实时更新)的形式在当前工作区右上角看到下面的 300x150 屏幕截图。

在此处输入图片描述

答案1

编辑

(新答案)

完毕。
下面的答案现在以完善的形式提供,作为指标,作为 Trusty、Xenial、Yakkety 和 Zesty 的 ppa:

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

指示器(包括预览窗口)现在电量不足。选项包括设置窗口、设置窗口边框大小/颜色、窗口大小。

在此处输入图片描述

与此同时,我发现关注 AU 窗口很有用;看看是否有任何消息:)


旧答案

第一秒粗略的概念)

在另一个工作区上最小化显示窗口

令我(大为)惊讶的是,它可以是有效地完成了,无论是使用诡计还是欺骗;在另一个工作区上有一个更新的窗口表示。不是适合观看电影,绝对足以关注其他地方的窗口(例如:我的电视卡窗口):

实践中如何运作

  1. 在窗口前面,按下快捷键:

    在此处输入图片描述

    (窗口将最小化)

  2. 移动到另一个工作区,再次按下快捷键,将出现一个小窗口,每 4 秒更新一次:

    在此处输入图片描述

    该窗口始终显示在其他窗口之上。窗口本来是 300px(宽度),但可以设置为任意大小。

  3. 要结束它,请(再次)按下快捷键。小窗口将关闭,您将移动到原始窗口的视口,该窗口将再次出现,未最小化。

脚本

  1. 控制脚本

    #!/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. 窗口表示

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

如何使用

  1. 安装python3-pilxdotool然后wmctrl

    sudo apt-get install xdotool wmctrl python3-pil
    
  2. 如果目录尚不存在,则创建该目录~/bin

  3. 复制脚本 1,即控制脚本,与showcase_control中的(完全相同)(无扩展名)相同~/bin,并且使其可执行
  4. 复制脚本 2,即迷你窗口脚本,与showmin中的(完全一样)(无扩展名)相同~/bin,并且使其可执行
  5. 注销并重新登录,并将以下命令添加到您选择的快捷方式中:

    showcase_control
    

    选择:系统设置 > “键盘” > “快捷键” > “自定义快捷键”。点击“+”并添加命令:

    showcase_control
    

    它应该可以工作!

    • 按一次键抓取当前窗口
    • 移动到你想要迷你窗口的其他工作区
    • 再次按下显示迷你窗口
    • 再次按下可返回到原始工作区,(自动)取消最小化原始窗口并关闭迷你窗口。

缺点?

  • 目前的设置是添加一些适用于您的处理器。然而,在我的(非常)旧系统上,它(平均)增加了大约 4-5%,我估计,我没有注意到任何方式。

    更新:事实证明,import可以一步调整图像大小,再加上获取窗口图像。这意味着处理器负载大幅减少。同时刷新时间更短(现在为 3 秒),但“成本”仍然较低。

解释

  • 我的出发点是 OP 提到的他想使用该选项来关注另一个工作区上的窗口,等待某件事完成。
  • 尽管字面上地在另一个工作区上拥有一个窗口的精确(微型)副本似乎是不可能的,我们一旦我们有了窗口 ID,就可以使用 -command 为现有窗口创建图像import。虽然这两者都适用于最小化窗口或无焦点窗口,但有一个问题:窗口需要在当前工作区
  • 诀窍是暂时(使用迷你窗口时)使窗口“粘滞” (几乎在所有工作区上可用) wmctrl,但同时最小化。
  • 由于一切都是自动完成的,区别有效地是无,因为返回初始视口、取消粘性原始窗口以及取消最小化它都是自动完成的。

简而言之:

  1. 按一次快捷键:目标窗口变为粘性,但最小化
  2. 再次按下它(大概在另一个工作区):左上角会出现一个小型的窗口版本,每四秒更新一次。
  3. 再次按下:迷你窗口关闭,桌面移动到窗口的初始工作区,窗口恢复为非粘性且非最小化。

专门针对 VirtualBox

当 VBox 窗口在前面时,Ubuntu 快捷键被禁用了(!),因此需要以另一种方式启动控制脚本。下面是一些简要的。

选项1

我编辑了控制脚本。现在仅有的对于 VirtualBox 来说:

  • 点击任何地方在桌面上,然后按下快捷键。之后,只需使用快捷键即可显示窗口并退出。

    解释:如果窗口类型为“桌面”,则控制脚本将退出,因为您不想最小化桌面。现在,如果当前活动窗口是桌面,则脚本首先查找可能存在的 VirtualBox 窗口作为目标。

选项 2

  • 复制下面的图标(右键->另存为),另存为minwinicon.png

    在此处输入图片描述

  • 将以下行复制到一个空文件中,并将其保存minwin.desktop~/.local/share/applications

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

    您需要注销并重新登录,以便启动器“找到”本地~/bin路径!
    将图标拖到启动器上即可使用它。

第二种解决方案有一个重要的缺点:从启动器使用它后,它会持续闪烁几秒钟,等待窗口出现。在此期间,再次点击不会有任何效果。得到解决,如上所述这里,但将其包含在这个答案中确实会使其太长。如果您想使用选项二,请查看链接。

答案2

有些事情看似过度,但对于这个目的来说却完全有效,那就是开放广播公司。在“来源”列表框中,单击加号,选择“窗口捕获”,然后按照提示选择您感兴趣的窗口。无需点击录制;只需使用预览即可。它可用于几乎任何操作系统,附有 Ubuntu 说明这里,我已将其复制如下。

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

如果您愿意,您可以进入“查看”菜单并隐藏所有 UI 元素。

相关内容